From 50e72fa660a2cac2c245b17cc0bd381e13ffbd0f Mon Sep 17 00:00:00 2001 From: eltitanb Date: Thu, 10 Jul 2025 13:42:25 +0100 Subject: [PATCH 01/12] rm deneb --- crates/common/src/pbs/types/beacon_block.rs | 79 ++----------- .../src/pbs/types/blinded_block_body.rs | 42 ------- .../common/src/pbs/types/execution_payload.rs | 6 +- crates/common/src/pbs/types/get_header.rs | 104 +++--------------- crates/common/src/pbs/types/mod.rs | 10 +- crates/common/src/pbs/types/spec.rs | 31 ------ ...eb.json => execution-payload-electra.json} | 0 ...eneb.ssz => execution-payload-electra.ssz} | 0 crates/common/src/pbs/types/utils.rs | 11 +- crates/pbs/src/mev_boost/get_header.rs | 32 +----- crates/pbs/src/mev_boost/submit_block.rs | 58 +--------- tests/data/submit_block_response_holesky.json | 2 +- tests/src/mock_relay.rs | 6 +- tests/tests/pbs_get_header.rs | 8 +- 14 files changed, 47 insertions(+), 342 deletions(-) rename crates/common/src/pbs/types/testdata/{execution-payload-deneb.json => execution-payload-electra.json} (100%) rename crates/common/src/pbs/types/testdata/{execution-payload-deneb.ssz => execution-payload-electra.ssz} (100%) diff --git a/crates/common/src/pbs/types/beacon_block.rs b/crates/common/src/pbs/types/beacon_block.rs index afcc9608..f377123a 100644 --- a/crates/common/src/pbs/types/beacon_block.rs +++ b/crates/common/src/pbs/types/beacon_block.rs @@ -3,11 +3,8 @@ use serde::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; use super::{ - blinded_block_body::{BlindedBeaconBlockBodyDeneb, BlindedBeaconBlockBodyElectra}, - blobs_bundle::BlobsBundle, - execution_payload::ExecutionPayload, - spec::{DenebSpec, ElectraSpec}, - utils::VersionedResponse, + blinded_block_body::BlindedBeaconBlockBodyElectra, blobs_bundle::BlobsBundle, + execution_payload::ExecutionPayload, spec::ElectraSpec, utils::VersionedResponse, }; #[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] @@ -21,28 +18,24 @@ impl SignedBlindedBeaconBlock { pub fn block_hash(&self) -> B256 { match &self.message { BlindedBeaconBlock::Electra(b) => b.body.execution_payload_header.block_hash, - BlindedBeaconBlock::Deneb(b) => b.body.execution_payload_header.block_hash, } } pub fn block_number(&self) -> u64 { match &self.message { BlindedBeaconBlock::Electra(b) => b.body.execution_payload_header.block_number, - BlindedBeaconBlock::Deneb(b) => b.body.execution_payload_header.block_number, } } pub fn parent_hash(&self) -> B256 { match &self.message { BlindedBeaconBlock::Electra(b) => b.body.execution_payload_header.parent_hash, - BlindedBeaconBlock::Deneb(b) => b.body.execution_payload_header.parent_hash, } } pub fn slot(&self) -> u64 { match &self.message { BlindedBeaconBlock::Electra(b) => b.slot, - BlindedBeaconBlock::Deneb(b) => b.slot, } } } @@ -51,27 +44,15 @@ impl SignedBlindedBeaconBlock { #[serde(untagged)] #[ssz(enum_behaviour = "transparent")] pub enum BlindedBeaconBlock { - Deneb(BlindedBeaconBlockDeneb), Electra(BlindedBeaconBlockElectra), } impl Default for BlindedBeaconBlock { fn default() -> Self { - Self::Deneb(BlindedBeaconBlockDeneb::default()) + Self::Electra(BlindedBeaconBlockElectra::default()) } } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] -pub struct BlindedBeaconBlockDeneb { - #[serde(with = "serde_utils::quoted_u64")] - pub slot: u64, - #[serde(with = "serde_utils::quoted_u64")] - pub proposer_index: u64, - pub parent_root: B256, - pub state_root: B256, - pub body: BlindedBeaconBlockBodyDeneb, -} - #[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] pub struct BlindedBeaconBlockElectra { #[serde(with = "serde_utils::quoted_u64")] @@ -84,30 +65,16 @@ pub struct BlindedBeaconBlockElectra { } /// Returned by relay in submit_block -pub type SubmitBlindedBlockResponse = - VersionedResponse; +pub type SubmitBlindedBlockResponse = VersionedResponse; impl SubmitBlindedBlockResponse { pub fn block_hash(&self) -> B256 { match self { - VersionedResponse::Deneb(d) => d.block_hash(), VersionedResponse::Electra(d) => d.block_hash(), } } } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] -pub struct PayloadAndBlobsDeneb { - pub execution_payload: ExecutionPayload, - pub blobs_bundle: BlobsBundle, -} - -impl PayloadAndBlobsDeneb { - pub fn block_hash(&self) -> B256 { - self.execution_payload.block_hash - } -} - #[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] pub struct PayloadAndBlobsElectra { pub execution_payload: ExecutionPayload, @@ -128,23 +95,6 @@ mod tests { use super::*; use crate::utils::{test_encode_decode, test_encode_decode_ssz}; - #[test] - // this is from the builder api spec, but with sync_committee_bits fixed to - // deserialize correctly - fn test_signed_blinded_block_deneb() { - let data = include_str!("testdata/signed-blinded-beacon-block-deneb-2.json"); - let block = test_encode_decode::(&data); - assert!(matches!(block.message, BlindedBeaconBlock::Deneb(_))); - } - - #[test] - // this is from mev-boost test data - fn test_signed_blinded_block_fb_deneb() { - let data = include_str!("testdata/signed-blinded-beacon-block-deneb.json"); - let block = test_encode_decode::(&data); - assert!(matches!(block.message, BlindedBeaconBlock::Deneb(_))); - } - #[test] // this is from mev-boost test data fn test_signed_blinded_block_fb_electra() { @@ -156,11 +106,11 @@ mod tests { #[test] // this is from the builder api spec, but with blobs fixed to deserialize // correctly - fn test_submit_blinded_block_response_deneb() { + fn test_submit_blinded_block_response_electra() { let blob = alloy::primitives::hex::encode_prefixed([1; 131072]); let data = json!({ - "version": "deneb", + "version": "electra", "data": { "execution_payload": { "parent_hash": @@ -209,7 +159,7 @@ mod tests { }).to_string(); let block = test_encode_decode::(&data); - assert!(matches!(block, SubmitBlindedBlockResponse::Deneb(_))); + assert!(matches!(block, SubmitBlindedBlockResponse::Electra(_))); } #[test] @@ -230,21 +180,10 @@ mod tests { #[test] // this is dummy data generated with https://github.com/attestantio/go-builder-client fn test_execution_payload_block_ssz() { - let data_json = include_str!("testdata/execution-payload-deneb.json"); - let block_json = test_encode_decode::(&data_json); - - let data_ssz = include_bytes!("testdata/execution-payload-deneb.ssz"); - let data_ssz = alloy::primitives::hex::decode(data_ssz).unwrap(); - test_encode_decode_ssz::(&data_ssz); - - assert_eq!(block_json.as_ssz_bytes(), data_ssz); - - // electra and deneb have the same execution payload - - let data_json = include_str!("testdata/execution-payload-deneb.json"); + let data_json = include_str!("testdata/execution-payload-electra.json"); let block_json = test_encode_decode::(&data_json); - let data_ssz = include_bytes!("testdata/execution-payload-deneb.ssz"); + let data_ssz = include_bytes!("testdata/execution-payload-electra.ssz"); let data_ssz = alloy::primitives::hex::decode(data_ssz).unwrap(); test_encode_decode_ssz::(&data_ssz); diff --git a/crates/common/src/pbs/types/blinded_block_body.rs b/crates/common/src/pbs/types/blinded_block_body.rs index 843e6f2e..966aa1e5 100644 --- a/crates/common/src/pbs/types/blinded_block_body.rs +++ b/crates/common/src/pbs/types/blinded_block_body.rs @@ -11,24 +11,6 @@ use super::{ kzg::KzgCommitments, spec::EthSpec, utils::*, }; -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] -#[serde(deny_unknown_fields)] -pub struct BlindedBeaconBlockBodyDeneb { - pub randao_reveal: BlsSignature, - pub eth1_data: Eth1Data, - pub graffiti: B256, - pub proposer_slashings: VariableList, - pub attester_slashings: VariableList, T::MaxAttesterSlashings>, - pub attestations: VariableList, T::MaxAttestations>, - pub deposits: VariableList, - pub voluntary_exits: VariableList, - pub sync_aggregate: SyncAggregate, - pub execution_payload_header: ExecutionPayloadHeader, - pub bls_to_execution_changes: - VariableList, - pub blob_kzg_commitments: KzgCommitments, -} - #[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] #[serde(deny_unknown_fields)] pub struct BlindedBeaconBlockBodyElectra { @@ -93,28 +75,12 @@ pub struct ProposerSlashing { pub signed_header_2: SignedBeaconBlockHeader, } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] -pub struct AttesterSlashingDeneb { - pub attestation_1: IndexedAttestationDeneb, - pub attestation_2: IndexedAttestationDeneb, -} - #[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] pub struct AttesterSlashingElectra { pub attestation_1: IndexedAttestationElectra, pub attestation_2: IndexedAttestationElectra, } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] -#[serde(bound = "T: EthSpec")] -pub struct IndexedAttestationDeneb { - /// Lists validator registry indices, not committee indices. - #[serde(with = "quoted_variable_list_u64")] - pub attesting_indices: VariableList, - pub data: AttestationData, - pub signature: BlsSignature, -} - #[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] #[serde(bound = "T: EthSpec")] pub struct IndexedAttestationElectra { @@ -145,14 +111,6 @@ pub struct Checkpoint { pub root: B256, } -#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] -#[serde(bound = "T: EthSpec")] -pub struct AttestationDeneb { - pub aggregation_bits: BitList, - pub data: AttestationData, - pub signature: BlsSignature, -} - #[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] #[serde(bound = "T: EthSpec")] pub struct AttestationElectra { diff --git a/crates/common/src/pbs/types/execution_payload.rs b/crates/common/src/pbs/types/execution_payload.rs index 8945121d..f851e8da 100644 --- a/crates/common/src/pbs/types/execution_payload.rs +++ b/crates/common/src/pbs/types/execution_payload.rs @@ -95,13 +95,13 @@ mod tests { use super::*; use crate::{ - pbs::types::{execution_payload::Transactions, spec::DenebSpec}, + pbs::{types::execution_payload::Transactions, ElectraSpec}, utils::test_encode_decode, }; #[test] fn test_empty_tx_root_hash() { - let txs: Transactions = VariableList::empty(); + let txs: Transactions = VariableList::empty(); let txs_root = txs.tree_hash_root(); assert_eq!(txs_root, EMPTY_TX_ROOT_HASH); @@ -129,7 +129,7 @@ mod tests { "excess_blob_gas": "95158272" }"#; - let parsed = test_encode_decode::>(&data); + let parsed = test_encode_decode::>(&data); assert_eq!( parsed.parent_hash, diff --git a/crates/common/src/pbs/types/get_header.rs b/crates/common/src/pbs/types/get_header.rs index 954aca66..76cde408 100644 --- a/crates/common/src/pbs/types/get_header.rs +++ b/crates/common/src/pbs/types/get_header.rs @@ -8,11 +8,8 @@ use ssz_derive::{Decode, Encode}; use tree_hash_derive::TreeHash; use super::{ - execution_payload::ExecutionPayloadHeader, - execution_requests::ExecutionRequests, - kzg::KzgCommitments, - spec::{DenebSpec, ElectraSpec}, - utils::VersionedResponse, + execution_payload::ExecutionPayloadHeader, execution_requests::ExecutionRequests, + kzg::KzgCommitments, spec::ElectraSpec, utils::VersionedResponse, }; #[derive(Debug, Serialize, Deserialize, Clone, Copy)] @@ -26,64 +23,54 @@ pub struct GetHeaderParams { } /// Returned by relay in get_header -pub type GetHeaderResponse = VersionedResponse< - SignedExecutionPayloadHeader, - SignedExecutionPayloadHeader, ->; +pub type GetHeaderResponse = + VersionedResponse>; impl GetHeaderResponse { pub fn block_number(&self) -> u64 { match self { - VersionedResponse::Deneb(data) => data.message.header.block_number, VersionedResponse::Electra(data) => data.message.header.block_number, } } pub fn block_hash(&self) -> B256 { match self { - VersionedResponse::Deneb(data) => data.message.header.block_hash, VersionedResponse::Electra(data) => data.message.header.block_hash, } } pub fn gas_limit(&self) -> u64 { match self { - VersionedResponse::Deneb(data) => data.message.header.gas_limit, VersionedResponse::Electra(data) => data.message.header.gas_limit, } } pub fn pubkey(&self) -> BlsPublicKey { match self { - VersionedResponse::Deneb(data) => data.message.pubkey, VersionedResponse::Electra(data) => data.message.pubkey, } } pub fn value(&self) -> U256 { match self { - VersionedResponse::Deneb(data) => data.message.value, VersionedResponse::Electra(data) => data.message.value, } } pub fn transactions_root(&self) -> B256 { match self { - GetHeaderResponse::Deneb(data) => data.message.header.transactions_root, GetHeaderResponse::Electra(data) => data.message.header.transactions_root, } } pub fn parent_hash(&self) -> B256 { match self { - GetHeaderResponse::Deneb(data) => data.message.header.parent_hash, GetHeaderResponse::Electra(data) => data.message.header.parent_hash, } } pub fn signautre(&self) -> BlsSignature { match self { - GetHeaderResponse::Deneb(data) => data.signature, GetHeaderResponse::Electra(data) => data.signature, } } @@ -95,15 +82,6 @@ pub struct SignedExecutionPayloadHeader { pub signature: BlsSignature, } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode, TreeHash)] -pub struct ExecutionPayloadHeaderMessageDeneb { - pub header: ExecutionPayloadHeader, - pub blob_kzg_commitments: KzgCommitments, - #[serde(with = "serde_utils::quoted_u256")] - pub value: U256, - pub pubkey: BlsPublicKey, -} - #[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode, TreeHash)] pub struct ExecutionPayloadHeaderMessageElectra { pub header: ExecutionPayloadHeader, @@ -127,63 +105,6 @@ mod tests { utils::{test_encode_decode, test_encode_decode_ssz}, }; - #[test] - fn test_get_header_deneb() { - let data = r#"{ - "version": "deneb", - "data": { - "message": { - "header": { - "parent_hash": "0x114d1897fefa402a01a653c21a7f1f1db049d1373a5e73a2d25d7a8045dc02a1", - "fee_recipient": "0x1268ad189526ac0b386faf06effc46779c340ee6", - "state_root": "0x53ffe6d7d4bbcc5ef71429ce82b3d7bbfffddaed89d53979bf4dca7af0dbe94c", - "receipts_root": "0x3d67a1bb141379c352c95126c4dd06a4fe086efdc00b6e919b050c84d79f4df2", - "logs_bloom": "0x05440404082f80182749948b189406732c7da48ce83013f11c02562c0d10cc714002025f21c1c64b21293e4c40c5b58e5404aed7922104002008019258ad7020097424e0b01d41eb474dc0cd26c0c9298c640692260452e27104ac808a050a0dc47187f40386108058b301007229b82f0d30bb082c72410043005e32a42c841841184260c0d744a4a9a190840048a4590011e00084ca62a8ce3a030d640350214fbedf09f041823266c491b128800802a200eb1048341000fa810323c4825804643b68ca2301c559881c0e944334c843016e0874010c81009100348a1900e0546014239b02e956940d1408c1824847516850d8de4a110495f3d9a4d8c00808a0", - "prev_randao": "0x0fde820be6404bcb71d7bbeee140c16cd28b1940a40fa8a4e2c493114a08b38a", - "block_number": "1598034", - "gas_limit": "30000000", - "gas_used": "21186389", - "timestamp": "1716481836", - "extra_data": "0x546974616e2028746974616e6275696c6465722e78797a29", - "base_fee_per_gas": "1266581747", - "block_hash": "0xef2ebdec55b9fa68137c0a3133c0010963bfe1dfbb45139c7d2def06f0591c6b", - "transactions_root": "0x6b2db9b2be28599e0bf11b31c9a91c238c190f49072421b3fdb0734117e97b45", - "withdrawals_root": "0x2daccf0e476ca3e2644afbd13b2621d55b4d515b813a3b867cdacea24bb352d1", - "blob_gas_used": "786432", - "excess_blob_gas": "95158272" - }, - "blob_kzg_commitments": [ - "0xa20c71d1985996098aa63e8b5dc7b7fedb70de31478fe309dad3ac0e9b6d28d82be8e5e543021a0203dc785742e94b2f", - "0x94f367b25711d95dda009bdd4b055b8f433dc61a426e5f1ec70688b4c5fdd01c632c7fa4c71688161166f5ec6d90f9c9", - "0xb0d6874218fd27607effcd790eeb873d7114b9909942b9e7ccbbb78f02ddcb6f627c7cdfb91b0eb7e3982ba0d0024a2a", - "0x9576d096bb8bf8a6184afa070eac8ed92f2209be20b5ea46e2360653a9556d614e5f0779dbd9cedbc8e2933f74433c0c", - "0xa20c71d1985996098aa63e8b5dc7b7fedb70de31478fe309dad3ac0e9b6d28d82be8e5e543021a0203dc785742e94b2f", - "0xa20c71d1985996098aa63e8b5dc7b7fedb70de31478fe309dad3ac0e9b6d28d82be8e5e543021a0203dc785742e94b2f" - ], - "value": "4293912964927787", - "pubkey": "0xaa58208899c6105603b74396734a6263cc7d947f444f396a90f7b7d3e65d102aec7e5e5291b27e08d02c50a050825c2f" - }, - "signature": "0x8468517fd5ae1807d6b13a2c91e4d1d12b7249db0c63861095e054dfd801968c61b86ac270ac0dafcf84b486ee628d8e145cba65dcf126000f225d9adfe3e252a59d6e91b7fea9df6b7e6dfbb030567d4405e4522349c8f6eddf0f37afa2619e" - } - }"#; - - let parsed = test_encode_decode::(&data); - let VersionedResponse::Deneb(parsed) = parsed else { - panic!("parsed is not a Deneb response"); - }; - - assert_eq!(parsed.message.value, U256::from(4293912964927787u64)); - - assert!(verify_signed_message( - Chain::Holesky, - &parsed.message.pubkey.into(), - &parsed.message, - &parsed.signature, - APPLICATION_BUILDER_DOMAIN - ) - .is_ok()) - } - #[test] // from the builder api spec, the signature is a dummy so it's not checked fn test_get_header_electra() { @@ -239,18 +160,25 @@ mod tests { ] }, "value": "1", - "pubkey": "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a" + "pubkey": "0x86b1cea87eed94cad99244356abcd83995947670f0553a1d3fe83c4a9e8116f4891fb1c51db232e736be1cb3327164bc" }, - "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" + "signature": "0x8addecd35e0ffe27b74e41aff2836527e6fea0efdb46dbb0f7436f5087d0cd5665bd16d924f640fc928cdba0173971e400dc603dbd6310bfb6f249c1554b044fe06ae4cf5d5f452f3ff19d9d130809b34d3d3abdca3d192c839ba2ac91129c15" } }"#; let parsed = test_encode_decode::(&data); - let VersionedResponse::Electra(parsed) = parsed else { - panic!("parsed is not a Deneb response"); - }; + let VersionedResponse::Electra(parsed) = parsed; assert_eq!(parsed.message.value, U256::from(1)); + + assert!(verify_signed_message( + Chain::Holesky, + &parsed.message.pubkey, + &parsed.message, + &parsed.signature, + APPLICATION_BUILDER_DOMAIN + ) + .is_ok()) } #[test] diff --git a/crates/common/src/pbs/types/mod.rs b/crates/common/src/pbs/types/mod.rs index e649f43a..e22c4a2f 100644 --- a/crates/common/src/pbs/types/mod.rs +++ b/crates/common/src/pbs/types/mod.rs @@ -9,8 +9,8 @@ mod spec; mod utils; pub use beacon_block::{ - BlindedBeaconBlock, BlindedBeaconBlockDeneb, BlindedBeaconBlockElectra, PayloadAndBlobsDeneb, - PayloadAndBlobsElectra, SignedBlindedBeaconBlock, SubmitBlindedBlockResponse, + BlindedBeaconBlock, BlindedBeaconBlockElectra, PayloadAndBlobsElectra, + SignedBlindedBeaconBlock, SubmitBlindedBlockResponse, }; pub use blobs_bundle::{Blob, BlobsBundle}; pub use execution_payload::{ @@ -21,11 +21,11 @@ pub use execution_requests::{ ConsolidationRequest, DepositRequest, ExecutionRequests, WithdrawalRequest, }; pub use get_header::{ - ExecutionPayloadHeaderMessageDeneb, ExecutionPayloadHeaderMessageElectra, GetHeaderParams, - GetHeaderResponse, SignedExecutionPayloadHeader, + ExecutionPayloadHeaderMessageElectra, GetHeaderParams, GetHeaderResponse, + SignedExecutionPayloadHeader, }; pub use kzg::{ KzgCommitment, KzgCommitments, KzgProof, KzgProofs, BYTES_PER_COMMITMENT, BYTES_PER_PROOF, }; -pub use spec::{DenebSpec, ElectraSpec, EthSpec}; +pub use spec::{ElectraSpec, EthSpec}; pub use utils::VersionedResponse; diff --git a/crates/common/src/pbs/types/spec.rs b/crates/common/src/pbs/types/spec.rs index 966807c2..61bd90a4 100644 --- a/crates/common/src/pbs/types/spec.rs +++ b/crates/common/src/pbs/types/spec.rs @@ -29,37 +29,6 @@ pub trait EthSpec { type MaxWithdrawalRequestsPerPayload: typenum::Unsigned + std::fmt::Debug; } -#[derive(Debug, Default, Clone, Serialize, Deserialize)] -pub struct DenebSpec; - -impl EthSpec for DenebSpec { - type MaxValidatorsPerCommittee = typenum::U2048; - type MaxProposerSlashings = typenum::U16; - type MaxDeposits = typenum::U16; - type MaxVoluntaryExits = typenum::U16; - type SyncCommitteeSize = typenum::U512; - type MaxExtraDataBytes = typenum::U32; - type MaxBlobCommitmentsPerBlock = typenum::U4096; - type BytesPerLogsBloom = typenum::U256; - type MaxBlsToExecutionChanges = typenum::U16; - type MaxWithdrawalsPerPayload = typenum::U16; - type MaxBytesPerTransaction = typenum::U1073741824; - type MaxTransactionsPerPayload = typenum::U1048576; - type BytesPerBlob = typenum::U131072; - type MaxCommitteesPerSlot = typenum::U64; - - // Updated in Electra - type MaxAttesterSlashings = typenum::U2; - type MaxAttestations = typenum::U128; - - // Electra - type MaxValidatorsPerSlot = typenum::U131072; - - type MaxConsolidationRequestsPerPayload = typenum::U0; - type MaxDepositRequestsPerPayload = typenum::U0; - type MaxWithdrawalRequestsPerPayload = typenum::U0; -} - #[derive(Debug, Default, Clone, Serialize, Deserialize)] pub struct ElectraSpec; diff --git a/crates/common/src/pbs/types/testdata/execution-payload-deneb.json b/crates/common/src/pbs/types/testdata/execution-payload-electra.json similarity index 100% rename from crates/common/src/pbs/types/testdata/execution-payload-deneb.json rename to crates/common/src/pbs/types/testdata/execution-payload-electra.json diff --git a/crates/common/src/pbs/types/testdata/execution-payload-deneb.ssz b/crates/common/src/pbs/types/testdata/execution-payload-electra.ssz similarity index 100% rename from crates/common/src/pbs/types/testdata/execution-payload-deneb.ssz rename to crates/common/src/pbs/types/testdata/execution-payload-electra.ssz diff --git a/crates/common/src/pbs/types/utils.rs b/crates/common/src/pbs/types/utils.rs index 63b15b9b..8c66d357 100644 --- a/crates/common/src/pbs/types/utils.rs +++ b/crates/common/src/pbs/types/utils.rs @@ -31,23 +31,20 @@ pub mod quoted_variable_list_u64 { #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(tag = "version", content = "data")] -pub enum VersionedResponse { - #[serde(rename = "deneb")] - Deneb(D), +pub enum VersionedResponse { #[serde(rename = "electra")] Electra(E), } -impl Default for VersionedResponse { +impl Default for VersionedResponse { fn default() -> Self { - Self::Deneb(D::default()) + Self::Electra(E::default()) } } -impl VersionedResponse { +impl VersionedResponse { pub fn version(&self) -> &str { match self { - VersionedResponse::Deneb(_) => "deneb", VersionedResponse::Electra(_) => "electra", } } diff --git a/crates/pbs/src/mev_boost/get_header.rs b/crates/pbs/src/mev_boost/get_header.rs index e4922245..ce591ba1 100644 --- a/crates/pbs/src/mev_boost/get_header.rs +++ b/crates/pbs/src/mev_boost/get_header.rs @@ -362,34 +362,6 @@ async fn send_one_get_header( ); match &get_header_response { - VersionedResponse::Deneb(res) => { - let header_data = HeaderData { - block_hash: res.message.header.block_hash, - parent_hash: res.message.header.parent_hash, - tx_root: res.message.header.transactions_root, - value: res.message.value, - timestamp: res.message.header.timestamp, - }; - - validate_header_data( - &header_data, - chain, - params.parent_hash, - validation.min_bid_wei, - params.slot, - )?; - - if !validation.skip_sigverify { - validate_signature( - chain, - relay.pubkey(), - res.message.pubkey, - &res.message, - &res.signature, - )?; - } - } - VersionedResponse::Electra(res) => { let header_data = HeaderData { block_hash: res.message.header.block_hash, @@ -534,7 +506,7 @@ mod tests { }; use blst::min_pk; use cb_common::{ - pbs::{error::ValidationError, ExecutionPayloadHeaderMessageDeneb, EMPTY_TX_ROOT_HASH}, + pbs::{error::ValidationError, ExecutionPayloadHeaderMessageElectra, EMPTY_TX_ROOT_HASH}, signature::sign_builder_message, types::Chain, utils::timestamp_of_slot_start_sec, @@ -608,7 +580,7 @@ mod tests { .unwrap(); let pubkey = BlsPublicKey::from_slice(&secret_key.sk_to_pk().to_bytes()); - let message = ExecutionPayloadHeaderMessageDeneb::default(); + let message = ExecutionPayloadHeaderMessageElectra::default(); let signature = sign_builder_message(Chain::Holesky, &secret_key, &message); diff --git a/crates/pbs/src/mev_boost/submit_block.rs b/crates/pbs/src/mev_boost/submit_block.rs index abb9554f..f4d6a400 100644 --- a/crates/pbs/src/mev_boost/submit_block.rs +++ b/crates/pbs/src/mev_boost/submit_block.rs @@ -4,9 +4,9 @@ use axum::http::{HeaderMap, HeaderValue}; use cb_common::{ pbs::{ error::{PbsError, ValidationError}, - BlindedBeaconBlock, BlindedBeaconBlockDeneb, BlindedBeaconBlockElectra, - PayloadAndBlobsDeneb, PayloadAndBlobsElectra, RelayClient, SignedBlindedBeaconBlock, - SubmitBlindedBlockResponse, VersionedResponse, HEADER_START_TIME_UNIX_MS, + BlindedBeaconBlock, BlindedBeaconBlockElectra, PayloadAndBlobsElectra, RelayClient, + SignedBlindedBeaconBlock, SubmitBlindedBlockResponse, VersionedResponse, + HEADER_START_TIME_UNIX_MS, }, utils::{get_user_agent_with_version, utcnow_ms}, }; @@ -182,67 +182,15 @@ async fn send_submit_block( // request has different type so cant be deserialized in the wrong version, // response has a "version" field match (&signed_blinded_block.message, &block_response) { - ( - BlindedBeaconBlock::Deneb(signed_blinded_block), - VersionedResponse::Deneb(block_response), - ) => validate_unblinded_block_deneb(signed_blinded_block, block_response), - ( BlindedBeaconBlock::Electra(signed_blinded_block), VersionedResponse::Electra(block_response), ) => validate_unblinded_block_electra(signed_blinded_block, block_response), - - (BlindedBeaconBlock::Deneb(_), VersionedResponse::Electra(_)) => { - Err(PbsError::Validation(ValidationError::PayloadVersionMismatch { - request: "deneb", - response: "electra", - })) - } - - (BlindedBeaconBlock::Electra(_), VersionedResponse::Deneb(_)) => { - Err(PbsError::Validation(ValidationError::PayloadVersionMismatch { - request: "electra", - response: "deneb", - })) - } }?; Ok(block_response) } -fn validate_unblinded_block_deneb( - signed_blinded_block: &BlindedBeaconBlockDeneb, - block_response: &PayloadAndBlobsDeneb, -) -> Result<(), PbsError> { - let blobs = &block_response.blobs_bundle; - - let expected_commitments = &signed_blinded_block.body.blob_kzg_commitments; - if expected_commitments.len() != blobs.blobs.len() || - expected_commitments.len() != blobs.commitments.len() || - expected_commitments.len() != blobs.proofs.len() - { - return Err(PbsError::Validation(ValidationError::KzgCommitments { - expected_blobs: expected_commitments.len(), - got_blobs: blobs.blobs.len(), - got_commitments: blobs.commitments.len(), - got_proofs: blobs.proofs.len(), - })); - } - - for (i, comm) in expected_commitments.iter().enumerate() { - // this is safe since we already know they are the same length - if *comm != blobs.commitments[i] { - return Err(PbsError::Validation(ValidationError::KzgMismatch { - expected: format!("{comm}"), - got: format!("{}", blobs.commitments[i]), - index: i, - })); - } - } - - Ok(()) -} - fn validate_unblinded_block_electra( signed_blinded_block: &BlindedBeaconBlockElectra, block_response: &PayloadAndBlobsElectra, diff --git a/tests/data/submit_block_response_holesky.json b/tests/data/submit_block_response_holesky.json index e2f2a171..8563f82c 100644 --- a/tests/data/submit_block_response_holesky.json +++ b/tests/data/submit_block_response_holesky.json @@ -1,5 +1,5 @@ { - "version": "deneb", + "version": "electra", "data": { "execution_payload": { "parent_hash": "0x7d1b19deda3378ae27947d8ad904886cde4600fe0f4d608c6ecd742d1ba8181b", diff --git a/tests/src/mock_relay.rs b/tests/src/mock_relay.rs index c70efa56..a91a70c6 100644 --- a/tests/src/mock_relay.rs +++ b/tests/src/mock_relay.rs @@ -16,7 +16,7 @@ use axum::{ }; use cb_common::{ pbs::{ - ExecutionPayloadHeaderMessageDeneb, GetHeaderParams, GetHeaderResponse, + ExecutionPayloadHeaderMessageElectra, GetHeaderParams, GetHeaderResponse, SignedExecutionPayloadHeader, SubmitBlindedBlockResponse, BUILDER_API_PATH, GET_HEADER_PATH, GET_STATUS_PATH, REGISTER_VALIDATOR_PATH, SUBMIT_BLOCK_PATH, }, @@ -108,7 +108,7 @@ async fn handle_get_header( ) -> Response { state.received_get_header.fetch_add(1, Ordering::Relaxed); - let mut response: SignedExecutionPayloadHeader = + let mut response: SignedExecutionPayloadHeader = SignedExecutionPayloadHeader::default(); response.message.header.parent_hash = parent_hash; @@ -120,7 +120,7 @@ async fn handle_get_header( let object_root = response.message.tree_hash_root().0; response.signature = sign_builder_root(state.chain, &state.signer, object_root); - let response = GetHeaderResponse::Deneb(response); + let response = GetHeaderResponse::Electra(response); (StatusCode::OK, Json(response)).into_response() } diff --git a/tests/tests/pbs_get_header.rs b/tests/tests/pbs_get_header.rs index 747d460c..02cceb0a 100644 --- a/tests/tests/pbs_get_header.rs +++ b/tests/tests/pbs_get_header.rs @@ -48,13 +48,7 @@ async fn test_get_header() -> Result<()> { assert_eq!(res.status(), StatusCode::OK); let res = serde_json::from_slice::(&res.bytes().await?)?; - - let res = match res { - GetHeaderResponse::Deneb(data) => data, - GetHeaderResponse::Electra(_) => { - unreachable!() - } - }; + let GetHeaderResponse::Electra(res) = res; assert_eq!(mock_state.received_get_header(), 1); assert_eq!(res.message.header.block_hash.0[0], 1); From 3b7f7fedb935cef69b66b0377ab7502a6fe71770 Mon Sep 17 00:00:00 2001 From: eltitanb Date: Thu, 10 Jul 2025 22:43:00 +0100 Subject: [PATCH 02/12] unify bls --- Cargo.lock | 607 ++++++++++++++++-- Cargo.toml | 4 +- benches/pbs/src/main.rs | 16 +- bin/src/lib.rs | 4 +- crates/common/Cargo.toml | 4 +- crates/common/src/commit/client.rs | 5 +- crates/common/src/commit/request.rs | 29 +- crates/common/src/config/mux.rs | 32 +- crates/common/src/config/pbs.rs | 5 +- crates/common/src/config/utils.rs | 11 +- crates/common/src/error.rs | 58 -- crates/common/src/lib.rs | 1 - crates/common/src/pbs/error.rs | 11 +- crates/common/src/pbs/relay.rs | 39 +- crates/common/src/pbs/types/beacon_block.rs | 13 +- .../src/pbs/types/blinded_block_body.rs | 28 +- .../src/pbs/types/execution_requests.rs | 12 +- crates/common/src/pbs/types/get_header.rs | 23 +- crates/common/src/pbs/types/mod.rs | 4 + crates/common/src/signature.rs | 43 +- crates/common/src/signer/loader.rs | 40 +- crates/common/src/signer/schemes/bls.rs | 53 +- crates/common/src/signer/schemes/ecdsa.rs | 8 +- crates/common/src/signer/store.rs | 190 +++--- crates/common/src/signer/types.rs | 3 +- crates/common/src/types.rs | 14 +- crates/common/src/utils.rs | 20 +- crates/pbs/Cargo.toml | 1 - crates/pbs/src/mev_boost/get_header.rs | 71 +- crates/pbs/src/routes/get_header.rs | 4 +- crates/pbs/src/state.rs | 3 +- crates/signer/src/manager/dirk.rs | 100 +-- crates/signer/src/manager/local.rs | 94 +-- crates/signer/src/service.rs | 10 +- examples/da_commit/src/main.rs | 9 +- tests/src/mock_relay.rs | 38 +- tests/src/mock_validator.rs | 30 +- ...signed-blinded-beacon-block-electra-2.json | 223 +++++++ tests/src/utils.rs | 4 +- tests/tests/pbs_get_header.rs | 23 +- tests/tests/pbs_get_status.rs | 12 +- tests/tests/pbs_mux.rs | 19 +- tests/tests/pbs_post_blinded_blocks.rs | 19 +- tests/tests/pbs_post_validators.rs | 14 +- tests/tests/signer_jwt_auth.rs | 7 +- 45 files changed, 1301 insertions(+), 657 deletions(-) delete mode 100644 crates/common/src/error.rs create mode 100644 tests/src/signed-blinded-beacon-block-electra-2.json diff --git a/Cargo.lock b/Cargo.lock index 5182a760..d098325f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,6 +41,18 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "aho-corasick" version = "1.1.3" @@ -234,7 +246,7 @@ dependencies = [ "c-kzg", "derive_more 2.0.1", "either", - "ethereum_ssz 0.8.3", + "ethereum_ssz", "ethereum_ssz_derive", "once_cell", "serde", @@ -326,9 +338,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eacedba97e65cdc7ab592f2b22ef5d3ab8d60b2056bc3a6e6363577e8270ec6f" dependencies = [ "alloy-rlp", + "arbitrary", "bytes", "cfg-if", "const-hex", + "derive_arbitrary", "derive_more 2.0.1", "foldhash", "getrandom 0.2.15", @@ -339,6 +353,7 @@ dependencies = [ "keccak-asm", "paste", "proptest", + "proptest-derive", "rand 0.8.5", "ruint", "rustc-hash", @@ -507,12 +522,12 @@ dependencies = [ "alloy-eips", "alloy-primitives", "alloy-rpc-types-engine", - "ethereum_ssz 0.8.3", + "ethereum_ssz", "ethereum_ssz_derive", "serde", "serde_with", "thiserror 2.0.12", - "tree_hash 0.9.1", + "tree_hash", "tree_hash_derive", ] @@ -538,7 +553,7 @@ dependencies = [ "alloy-rlp", "alloy-serde", "derive_more 2.0.1", - "ethereum_ssz 0.8.3", + "ethereum_ssz", "ethereum_ssz_derive", "rand 0.8.5", "serde", @@ -875,6 +890,15 @@ dependencies = [ "derive_arbitrary", ] +[[package]] +name = "archery" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a8da9bc4c4053ee067669762bcaeea6e241841295a2b6c948312dad6ef4cc02" +dependencies = [ + "static_assertions", +] + [[package]] name = "ark-ff" version = "0.3.0" @@ -1279,6 +1303,12 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "bitflags" version = "2.9.0" @@ -1318,20 +1348,20 @@ dependencies = [ [[package]] name = "bls" version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse?tag=v7.0.1#e42406d7b79a85ad4622f3a7440ff6468ac4c9e1" +source = "git+https://github.com/sigp/lighthouse?tag=v7.1.0#cfb1f7331064b758c6786e4e1dc15507af5ff5d1" dependencies = [ "alloy-primitives", "arbitrary", "blst", "ethereum_hashing", "ethereum_serde_utils", - "ethereum_ssz 0.7.1", + "ethereum_ssz", "fixed_bytes", "hex", "rand 0.8.5", "safe_arith", "serde", - "tree_hash 0.8.0", + "tree_hash", "zeroize", ] @@ -1374,6 +1404,22 @@ dependencies = [ "zeroize", ] +[[package]] +name = "blstrs" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a8a8ed6fefbeef4a8c7b460e4110e12c5e22a5b7cf32621aae6ad650c4dcf29" +dependencies = [ + "blst", + "byte-slice-cast", + "ff", + "group", + "pairing", + "rand_core 0.6.4", + "serde", + "subtle", +] + [[package]] name = "blstrs_plus" version = "0.8.18" @@ -1484,14 +1530,13 @@ dependencies = [ "axum 0.8.1", "base64 0.22.1", "bimap", - "blst", "cipher 0.4.4", "ctr 0.9.2", "derive_more 2.0.1", "docker-image", "eth2_keystore", "ethereum_serde_utils", - "ethereum_ssz 0.8.3", + "ethereum_ssz", "ethereum_ssz_derive", "eyre", "jsonwebtoken", @@ -1511,8 +1556,9 @@ dependencies = [ "tracing", "tracing-appender", "tracing-subscriber", - "tree_hash 0.9.1", + "tree_hash", "tree_hash_derive", + "types", "unicode-normalization", "url", ] @@ -1538,7 +1584,6 @@ dependencies = [ "async-trait", "axum 0.8.1", "axum-extra", - "blst", "cb-common", "cb-metrics", "eyre", @@ -1550,7 +1595,7 @@ dependencies = [ "serde_json", "tokio", "tracing", - "tree_hash 0.9.1", + "tree_hash", "url", "uuid 1.16.0", ] @@ -1580,7 +1625,7 @@ dependencies = [ "tonic", "tonic-build", "tracing", - "tree_hash 0.9.1", + "tree_hash", "uuid 1.16.0", ] @@ -1600,7 +1645,7 @@ dependencies = [ "tokio", "tracing", "tracing-subscriber", - "tree_hash 0.9.1", + "tree_hash", "url", ] @@ -1670,7 +1715,7 @@ dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim", + "strsim 0.11.1", ] [[package]] @@ -1749,10 +1794,27 @@ dependencies = [ "eyre", "tokio", "tracing", - "tree_hash 0.9.1", + "tree_hash", "tree_hash_derive", ] +[[package]] +name = "compare_fields" +version = "0.2.0" +source = "git+https://github.com/sigp/lighthouse?tag=v7.1.0#cfb1f7331064b758c6786e4e1dc15507af5ff5d1" +dependencies = [ + "itertools 0.10.5", +] + +[[package]] +name = "compare_fields_derive" +version = "0.2.0" +source = "git+https://github.com/sigp/lighthouse?tag=v7.1.0#cfb1f7331064b758c6786e4e1dc15507af5ff5d1" +dependencies = [ + "quote", + "syn 1.0.109", +] + [[package]] name = "const-hex" version = "1.14.0" @@ -1792,6 +1854,25 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "context_deserialize" +version = "0.1.0" +source = "git+https://github.com/sigp/lighthouse?tag=v7.1.0#cfb1f7331064b758c6786e4e1dc15507af5ff5d1" +dependencies = [ + "milhouse", + "serde", + "ssz_types", +] + +[[package]] +name = "context_deserialize_derive" +version = "0.1.0" +source = "git+https://github.com/sigp/lighthouse?tag=v7.1.0#cfb1f7331064b758c6786e4e1dc15507af5ff5d1" +dependencies = [ + "quote", + "syn 1.0.109", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -1826,6 +1907,58 @@ dependencies = [ "libc", ] +[[package]] +name = "crate_crypto_internal_eth_kzg_bls12_381" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f9cdad245e39a3659bc4c8958e93de34bd31ba3131ead14ccfb4b2cd60e52d" +dependencies = [ + "blst", + "blstrs", + "ff", + "group", + "pairing", + "subtle", +] + +[[package]] +name = "crate_crypto_internal_eth_kzg_erasure_codes" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581d28bcc93eecd97a04cebc5293271e0f41650f03c102f24d6cd784cbedb9f2" +dependencies = [ + "crate_crypto_internal_eth_kzg_bls12_381", + "crate_crypto_internal_eth_kzg_polynomial", +] + +[[package]] +name = "crate_crypto_internal_eth_kzg_maybe_rayon" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06fc0f984e585ea984a766c5b58d6bf6c51e463b0a0835b0dd4652d358b506b3" + +[[package]] +name = "crate_crypto_internal_eth_kzg_polynomial" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56dff7a45e2d80308b21abdbc5520ec23c3ebfb3a94fafc02edfa7f356af6d7f" +dependencies = [ + "crate_crypto_internal_eth_kzg_bls12_381", +] + +[[package]] +name = "crate_crypto_kzg_multi_open_fk20" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a0c2f82695a88809e713e1ff9534cb90ceffab0a08f4bd33245db711f9d356f" +dependencies = [ + "crate_crypto_internal_eth_kzg_bls12_381", + "crate_crypto_internal_eth_kzg_maybe_rayon", + "crate_crypto_internal_eth_kzg_polynomial", + "hex", + "sha2 0.10.8", +] + [[package]] name = "crc" version = "3.2.1" @@ -1881,7 +2014,7 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" dependencies = [ - "bitflags", + "bitflags 2.9.0", "crossterm_winapi", "parking_lot", "rustix 0.38.44", @@ -1969,14 +2102,38 @@ dependencies = [ "tracing", ] +[[package]] +name = "darling" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" +dependencies = [ + "darling_core 0.13.4", + "darling_macro 0.13.4", +] + [[package]] name = "darling" version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" dependencies = [ - "darling_core", - "darling_macro", + "darling_core 0.20.10", + "darling_macro 0.20.10", +] + +[[package]] +name = "darling_core" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn 1.0.109", ] [[package]] @@ -1989,17 +2146,28 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim", + "strsim 0.11.1", "syn 2.0.100", ] +[[package]] +name = "darling_macro" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" +dependencies = [ + "darling_core 0.13.4", + "quote", + "syn 1.0.109", +] + [[package]] name = "darling_macro" version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ - "darling_core", + "darling_core 0.20.10", "quote", "syn 2.0.100", ] @@ -2081,7 +2249,7 @@ version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" dependencies = [ - "darling", + "darling 0.20.10", "proc-macro2", "quote", "syn 2.0.100", @@ -2219,6 +2387,18 @@ dependencies = [ "spki", ] +[[package]] +name = "educe" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7bc049e1bd8cdeb31b68bbd586a9464ecf9f3944af3958a7a9d0f8b9799417" +dependencies = [ + "enum-ordinalize", + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "either" version = "1.15.0" @@ -2258,6 +2438,26 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "enum-ordinalize" +version = "4.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea0dcfa4e54eeb516fe454635a95753ddd39acda650ce703031c6973e315dd5" +dependencies = [ + "enum-ordinalize-derive", +] + +[[package]] +name = "enum-ordinalize-derive" +version = "4.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -2274,10 +2474,23 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "eth2_interop_keypairs" +version = "0.2.0" +source = "git+https://github.com/sigp/lighthouse?tag=v7.1.0#cfb1f7331064b758c6786e4e1dc15507af5ff5d1" +dependencies = [ + "bls", + "ethereum_hashing", + "hex", + "num-bigint", + "serde", + "serde_yaml", +] + [[package]] name = "eth2_key_derivation" version = "0.1.0" -source = "git+https://github.com/sigp/lighthouse?tag=v7.0.1#e42406d7b79a85ad4622f3a7440ff6468ac4c9e1" +source = "git+https://github.com/sigp/lighthouse?tag=v7.1.0#cfb1f7331064b758c6786e4e1dc15507af5ff5d1" dependencies = [ "bls", "num-bigint-dig", @@ -2289,7 +2502,7 @@ dependencies = [ [[package]] name = "eth2_keystore" version = "0.1.0" -source = "git+https://github.com/sigp/lighthouse?tag=v7.0.1#e42406d7b79a85ad4622f3a7440ff6468ac4c9e1" +source = "git+https://github.com/sigp/lighthouse?tag=v7.1.0#cfb1f7331064b758c6786e4e1dc15507af5ff5d1" dependencies = [ "aes 0.7.5", "bls", @@ -2332,17 +2545,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "ethereum_ssz" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e999563461faea0ab9bc0024e5e66adcee35881f3d5062f52f31a4070fe1522" -dependencies = [ - "alloy-primitives", - "itertools 0.13.0", - "smallvec", -] - [[package]] name = "ethereum_ssz" version = "0.8.3" @@ -2350,6 +2552,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86da3096d1304f5f28476ce383005385459afeaf0eea08592b65ddbc9b258d16" dependencies = [ "alloy-primitives", + "arbitrary", "ethereum_serde_utils", "itertools 0.13.0", "serde", @@ -2364,7 +2567,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d832a5c38eba0e7ad92592f7a22d693954637fbb332b4f669590d66a5c3183e5" dependencies = [ - "darling", + "darling 0.20.10", "proc-macro2", "quote", "syn 2.0.100", @@ -2380,6 +2583,18 @@ dependencies = [ "once_cell", ] +[[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + [[package]] name = "fastrand" version = "2.3.0" @@ -2434,7 +2649,7 @@ dependencies = [ [[package]] name = "fixed_bytes" version = "0.1.0" -source = "git+https://github.com/sigp/lighthouse?tag=v7.0.1#e42406d7b79a85ad4622f3a7440ff6468ac4c9e1" +source = "git+https://github.com/sigp/lighthouse?tag=v7.1.0#cfb1f7331064b758c6786e4e1dc15507af5ff5d1" dependencies = [ "alloy-primitives", "safe_arith", @@ -2683,6 +2898,10 @@ name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", +] [[package]] name = "hashbrown" @@ -2696,6 +2915,15 @@ dependencies = [ "serde", ] +[[package]] +name = "hashlink" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +dependencies = [ + "hashbrown 0.14.5", +] + [[package]] name = "headers" version = "0.4.0" @@ -3121,6 +3349,7 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" dependencies = [ + "arbitrary", "equivalent", "hashbrown 0.15.2", "serde", @@ -3135,6 +3364,14 @@ dependencies = [ "generic-array 0.14.7", ] +[[package]] +name = "int_to_bytes" +version = "0.2.0" +source = "git+https://github.com/sigp/lighthouse?tag=v7.1.0#cfb1f7331064b758c6786e4e1dc15507af5ff5d1" +dependencies = [ + "bytes", +] + [[package]] name = "interprocess" version = "2.2.3" @@ -3251,6 +3488,25 @@ dependencies = [ "sha3-asm", ] +[[package]] +name = "kzg" +version = "0.1.0" +source = "git+https://github.com/sigp/lighthouse?tag=v7.1.0#cfb1f7331064b758c6786e4e1dc15507af5ff5d1" +dependencies = [ + "arbitrary", + "c-kzg", + "derivative", + "ethereum_hashing", + "ethereum_serde_utils", + "ethereum_ssz", + "ethereum_ssz_derive", + "hex", + "rust_eth_kzg", + "serde", + "serde_json", + "tree_hash", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -3272,6 +3528,17 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" +[[package]] +name = "libsqlite3-sys" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29f835d03d717946d28b1d1ed632eb6f0e24a299388ee623d0c23118d3e8a7fa" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + [[package]] name = "linux-raw-sys" version = "0.4.15" @@ -3326,6 +3593,12 @@ dependencies = [ "syn 2.0.100", ] +[[package]] +name = "maplit" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" + [[package]] name = "matchers" version = "0.1.0" @@ -3353,6 +3626,17 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "merkle_proof" +version = "0.2.0" +source = "git+https://github.com/sigp/lighthouse?tag=v7.1.0#cfb1f7331064b758c6786e4e1dc15507af5ff5d1" +dependencies = [ + "alloy-primitives", + "ethereum_hashing", + "fixed_bytes", + "safe_arith", +] + [[package]] name = "merlin" version = "3.0.0" @@ -3365,6 +3649,52 @@ dependencies = [ "zeroize", ] +[[package]] +name = "metastruct" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d74f54f231f9a18d77393ecc5cc7ab96709b2a61ee326c2b2b291009b0cc5a07" +dependencies = [ + "metastruct_macro", +] + +[[package]] +name = "metastruct_macro" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7225f3a4dfbec47a0c6a730a874185fda840d365d7bbd6ba199dd81796d5" +dependencies = [ + "darling 0.13.4", + "itertools 0.10.5", + "proc-macro2", + "quote", + "smallvec", + "syn 1.0.109", +] + +[[package]] +name = "milhouse" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb1ada1f56cc1c79f40517fdcbf57e19f60424a3a1ce372c3fe9b22e4fdd83eb" +dependencies = [ + "alloy-primitives", + "arbitrary", + "educe", + "ethereum_hashing", + "ethereum_ssz", + "ethereum_ssz_derive", + "itertools 0.13.0", + "parking_lot", + "rayon", + "serde", + "smallvec", + "tree_hash", + "triomphe", + "typenum", + "vec_map", +] + [[package]] name = "mime" version = "0.3.17" @@ -3558,7 +3888,7 @@ version = "0.10.71" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd" dependencies = [ - "bitflags", + "bitflags 2.9.0", "cfg-if", "foreign-types", "libc", @@ -3877,7 +4207,7 @@ checksum = "14cae93065090804185d3b75f0bf93b8eeda30c7a9b4a33d3bdb3988d6229e50" dependencies = [ "bit-set", "bit-vec", - "bitflags", + "bitflags 2.9.0", "lazy_static", "num-traits", "rand 0.8.5", @@ -3889,6 +4219,17 @@ dependencies = [ "unarray", ] +[[package]] +name = "proptest-derive" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee1c9ac207483d5e7db4940700de86a9aae46ef90c48b57f99fe7edb8345e49" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "prost" version = "0.13.5" @@ -4070,7 +4411,7 @@ version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" dependencies = [ - "bitflags", + "bitflags 2.9.0", ] [[package]] @@ -4197,6 +4538,15 @@ dependencies = [ "rustc-hex", ] +[[package]] +name = "rpds" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ef5140bcb576bfd6d56cd2de709a7d17851ac1f3805e67fe9d99e42a11821f" +dependencies = [ + "archery", +] + [[package]] name = "ruint" version = "1.13.1" @@ -4204,6 +4554,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "825df406ec217a8116bd7b06897c6cc8f65ffefc15d030ae2c9540acc9ed50b6" dependencies = [ "alloy-rlp", + "arbitrary", "ark-ff 0.3.0", "ark-ff 0.4.2", "bytes", @@ -4229,6 +4580,34 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" +[[package]] +name = "rusqlite" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01e213bc3ecb39ac32e81e51ebe31fd888a940515173e3a18a35f8c6e896422a" +dependencies = [ + "bitflags 1.3.2", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "smallvec", +] + +[[package]] +name = "rust_eth_kzg" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f83b5559e1dcd3f7721838909288faf4500fb466eff98eac99b67ac04335b93" +dependencies = [ + "crate_crypto_internal_eth_kzg_bls12_381", + "crate_crypto_internal_eth_kzg_erasure_codes", + "crate_crypto_kzg_multi_open_fk20", + "hex", + "serde", + "serde_json", +] + [[package]] name = "rustc-demangle" version = "0.1.24" @@ -4271,7 +4650,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags", + "bitflags 2.9.0", "errno", "libc", "linux-raw-sys 0.4.15", @@ -4284,7 +4663,7 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7178faa4b75a30e269c71e61c353ce2748cf3d76f0c44c393f4e60abf49b825" dependencies = [ - "bitflags", + "bitflags 2.9.0", "errno", "libc", "linux-raw-sys 0.9.3", @@ -4359,7 +4738,7 @@ checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "safe_arith" version = "0.1.0" -source = "git+https://github.com/sigp/lighthouse?tag=v7.0.1#e42406d7b79a85ad4622f3a7440ff6468ac4c9e1" +source = "git+https://github.com/sigp/lighthouse?tag=v7.1.0#cfb1f7331064b758c6786e4e1dc15507af5ff5d1" [[package]] name = "salsa20" @@ -4418,7 +4797,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags", + "bitflags 2.9.0", "core-foundation", "core-foundation-sys", "libc", @@ -4572,7 +4951,7 @@ version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d00caa5193a3c8362ac2b73be6b9e768aa5a4b2f721d8f4b339600c3cb51f8e" dependencies = [ - "darling", + "darling 0.20.10", "proc-macro2", "quote", "syn 2.0.100", @@ -4705,6 +5084,7 @@ version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" dependencies = [ + "arbitrary", "serde", ] @@ -4740,13 +5120,14 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dad0fa7e9a85c06d0a6ba5100d733fff72e231eb6db2d86078225cf716fd2d95" dependencies = [ + "arbitrary", "ethereum_serde_utils", - "ethereum_ssz 0.8.3", + "ethereum_ssz", "itertools 0.13.0", "serde", "serde_derive", "smallvec", - "tree_hash 0.9.1", + "tree_hash", "typenum", ] @@ -4779,6 +5160,12 @@ dependencies = [ "tracing", ] +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "strsim" version = "0.11.1" @@ -4813,6 +5200,30 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +[[package]] +name = "superstruct" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf0f31f730ad9e579364950e10d6172b4a9bd04b447edf5988b066a860cc340e" +dependencies = [ + "darling 0.13.4", + "itertools 0.10.5", + "proc-macro2", + "quote", + "smallvec", + "syn 1.0.109", +] + +[[package]] +name = "swap_or_not_shuffle" +version = "0.2.0" +source = "git+https://github.com/sigp/lighthouse?tag=v7.1.0#cfb1f7331064b758c6786e4e1dc15507af5ff5d1" +dependencies = [ + "alloy-primitives", + "ethereum_hashing", + "fixed_bytes", +] + [[package]] name = "syn" version = "1.0.109" @@ -4873,7 +5284,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags", + "bitflags 2.9.0", "core-foundation", "system-configuration-sys", ] @@ -4907,6 +5318,15 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "test_random_derive" +version = "0.2.0" +source = "git+https://github.com/sigp/lighthouse?tag=v7.1.0#cfb1f7331064b758c6786e4e1dc15507af5ff5d1" +dependencies = [ + "quote", + "syn 1.0.109", +] + [[package]] name = "thiserror" version = "1.0.69" @@ -5366,17 +5786,6 @@ dependencies = [ "tracing-serde", ] -[[package]] -name = "tree_hash" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "373495c23db675a5192de8b610395e1bec324d596f9e6111192ce903dc11403a" -dependencies = [ - "alloy-primitives", - "ethereum_hashing", - "smallvec", -] - [[package]] name = "tree_hash" version = "0.9.1" @@ -5385,7 +5794,7 @@ checksum = "6c58eb0f518840670270d90d97ffee702d8662d9c5494870c9e1e9e0fa00f668" dependencies = [ "alloy-primitives", "ethereum_hashing", - "ethereum_ssz 0.8.3", + "ethereum_ssz", "smallvec", "typenum", ] @@ -5396,12 +5805,22 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "699e7fb6b3fdfe0c809916f251cf5132d64966858601695c3736630a87e7166a" dependencies = [ - "darling", + "darling 0.20.10", "proc-macro2", "quote", "syn 2.0.100", ] +[[package]] +name = "triomphe" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef8f7726da4807b58ea5c96fdc122f80702030edc33b35aff9190a51148ccc85" +dependencies = [ + "serde", + "stable_deref_trait", +] + [[package]] name = "try-lock" version = "0.2.5" @@ -5433,6 +5852,56 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +[[package]] +name = "types" +version = "0.2.1" +source = "git+https://github.com/sigp/lighthouse?tag=v7.1.0#cfb1f7331064b758c6786e4e1dc15507af5ff5d1" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "arbitrary", + "bls", + "compare_fields", + "compare_fields_derive", + "context_deserialize", + "context_deserialize_derive", + "derivative", + "eth2_interop_keypairs", + "ethereum_hashing", + "ethereum_serde_utils", + "ethereum_ssz", + "ethereum_ssz_derive", + "fixed_bytes", + "hex", + "int_to_bytes", + "itertools 0.10.5", + "kzg", + "maplit", + "merkle_proof", + "metastruct", + "milhouse", + "parking_lot", + "rand 0.8.5", + "rand_xorshift", + "rayon", + "regex", + "rpds", + "rusqlite", + "safe_arith", + "serde", + "serde_json", + "serde_yaml", + "smallvec", + "ssz_types", + "superstruct", + "swap_or_not_shuffle", + "tempfile", + "test_random_derive", + "tracing", + "tree_hash", + "tree_hash_derive", +] + [[package]] name = "ucd-trie" version = "0.1.7" @@ -5580,6 +6049,12 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + [[package]] name = "version_check" version = "0.9.5" @@ -5985,7 +6460,7 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" dependencies = [ - "bitflags", + "bitflags 2.9.0", ] [[package]] @@ -6054,18 +6529,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.23" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.23" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index ff49bdea..f701ed07 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,6 @@ axum-extra = { version = "0.10.0", features = ["typed-header"] } base64 = "0.22.1" bimap = { version = "0.6.3", features = ["serde"] } blsful = "2.5" -blst = "0.3.11" cb-cli = { path = "crates/cli" } cb-common = { path = "crates/common" } cb-metrics = { path = "crates/metrics" } @@ -37,7 +36,6 @@ ctr = "0.9.2" derive_more = { version = "2.0.1", features = ["deref", "display", "from", "into"] } docker-compose-types = "0.16.0" docker-image = "0.2.1" -eth2_keystore = { git = "https://github.com/sigp/lighthouse", tag = "v7.0.1" } ethereum_serde_utils = "0.7.0" ethereum_ssz = "0.8" ethereum_ssz_derive = "0.8" @@ -47,6 +45,8 @@ headers = "0.4.0" indexmap = "2.2.6" jsonwebtoken = { version = "9.3.1", default-features = false } lazy_static = "1.5.0" +lh_eth2_keystore = { package = "eth2_keystore", git = "https://github.com/sigp/lighthouse", tag = "v7.1.0" } +lh_types = { package = "types", git = "https://github.com/sigp/lighthouse", tag = "v7.1.0" } parking_lot = "0.12.3" pbkdf2 = "0.12.2" prometheus = "0.13.4" diff --git a/benches/pbs/src/main.rs b/benches/pbs/src/main.rs index c013fd61..923823ac 100644 --- a/benches/pbs/src/main.rs +++ b/benches/pbs/src/main.rs @@ -1,12 +1,10 @@ use std::time::{Duration, Instant}; -use alloy::{primitives::B256, rpc::types::beacon::BlsPublicKey}; +use alloy::{hex, primitives::B256}; use cb_common::{ config::RelayConfig, - pbs::{GetHeaderResponse, RelayClient, RelayEntry}, - signer::BlsSecretKey, + pbs::{BlsPublicKey, BlsSecretKey, GetHeaderResponse, RelayClient, RelayEntry}, types::Chain, - utils::blst_pubkey_to_alloy, }; use cb_tests::mock_relay::{start_mock_relay_service, MockRelayState}; use comfy_table::Table; @@ -19,7 +17,7 @@ fn get_random_hash() -> B256 { B256::from(rand::random::<[u8; 32]>()) } fn get_random_pubkey() -> BlsPublicKey { - BlsPublicKey::ZERO + BlsPublicKey::deserialize(&hex!("0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")).unwrap() } #[tokio::main] @@ -47,7 +45,7 @@ async fn main() { for slot in 0..config.benchmark.n_slots { let parent_hash = get_random_hash(); let validator_pubkey = get_random_pubkey(); - let url = mock_validator.get_header_url(slot, parent_hash, validator_pubkey).unwrap(); + let url = mock_validator.get_header_url(slot, &parent_hash, &validator_pubkey).unwrap(); for _ in 0..config.benchmark.headers_per_slot { let url = url.clone(); @@ -138,8 +136,8 @@ 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 = BlsSecretKey::key_gen(&MOCK_RELAY_SECRET, &[]).unwrap(); - let pubkey: BlsPublicKey = blst_pubkey_to_alloy(&signer.sk_to_pk()); + let signer = BlsSecretKey::deserialize(&MOCK_RELAY_SECRET).unwrap(); + let pubkey: BlsPublicKey = signer.public_key(); assert_eq!(relay_config.entry.pubkey, pubkey, "Expected relay pubkey to be 0xb060572f535ba5615b874ebfef757fbe6825352ad257e31d724e57fe25a067a13cfddd0f00cb17bf3a3d2e901a380c17"); @@ -152,7 +150,7 @@ async fn start_mock_relay(chain: Chain, relay_config: RelayConfig) { } fn get_mock_validator(bench: BenchConfig) -> RelayClient { - let entry = RelayEntry { id: bench.id, pubkey: BlsPublicKey::default(), url: bench.url }; + let entry = RelayEntry { id: bench.id, pubkey: get_random_pubkey(), url: bench.url }; let config = RelayConfig { entry, id: None, diff --git a/bin/src/lib.rs b/bin/src/lib.rs index 126847b6..6f44c7f9 100644 --- a/bin/src/lib.rs +++ b/bin/src/lib.rs @@ -9,8 +9,8 @@ pub mod prelude { load_builder_module_config, load_commit_module_config, load_pbs_config, load_pbs_custom_config, LogsSettings, StartCommitModuleConfig, PBS_MODULE_NAME, }, - pbs::{BuilderEvent, BuilderEventClient, OnBuilderApiEvent}, - signer::{BlsPublicKey, BlsSignature, EcdsaSignature}, + pbs::{BlsPublicKey, BlsSignature, BuilderEvent, BuilderEventClient, OnBuilderApiEvent}, + signer::EcdsaSignature, types::Chain, utils::{initialize_tracing_log, utcnow_ms, utcnow_ns, utcnow_sec, utcnow_us}, }; diff --git a/crates/common/Cargo.toml b/crates/common/Cargo.toml index 6bcee533..a2a43d8a 100644 --- a/crates/common/Cargo.toml +++ b/crates/common/Cargo.toml @@ -12,17 +12,17 @@ async-trait.workspace = true axum.workspace = true base64.workspace = true bimap.workspace = true -blst.workspace = true cipher.workspace = true ctr.workspace = true derive_more.workspace = true docker-image.workspace = true -eth2_keystore.workspace = true ethereum_serde_utils.workspace = true ethereum_ssz.workspace = true ethereum_ssz_derive.workspace = true eyre.workspace = true jsonwebtoken.workspace = true +lh_eth2_keystore.workspace = true +lh_types.workspace = true pbkdf2.workspace = true rand.workspace = true rayon.workspace = true diff --git a/crates/common/src/commit/client.rs b/crates/common/src/commit/client.rs index 34413b65..d4af8b3d 100644 --- a/crates/common/src/commit/client.rs +++ b/crates/common/src/commit/client.rs @@ -1,6 +1,6 @@ use std::time::{Duration, Instant}; -use alloy::{primitives::Address, rpc::types::beacon::BlsSignature}; +use alloy::primitives::Address; use eyre::WrapErr; use reqwest::header::{HeaderMap, HeaderValue, AUTHORIZATION}; use serde::Deserialize; @@ -16,7 +16,8 @@ use super::{ }; use crate::{ constants::SIGNER_JWT_EXPIRATION, - signer::{BlsPublicKey, EcdsaSignature}, + pbs::{BlsPublicKey, BlsSignature}, + signer::EcdsaSignature, types::{Jwt, ModuleId}, utils::create_jwt, DEFAULT_REQUEST_TIMEOUT, diff --git a/crates/common/src/commit/request.rs b/crates/common/src/commit/request.rs index b8843234..a41b5648 100644 --- a/crates/common/src/commit/request.rs +++ b/crates/common/src/commit/request.rs @@ -6,7 +6,6 @@ use std::{ use alloy::{ hex, primitives::{Address, B256}, - rpc::types::beacon::BlsSignature, }; use derive_more::derive::From; use serde::{Deserialize, Serialize}; @@ -14,18 +13,30 @@ use tree_hash::TreeHash; use tree_hash_derive::TreeHash; use crate::{ - constants::COMMIT_BOOST_DOMAIN, error::BlstErrorWrapper, signature::verify_signed_message, - signer::BlsPublicKey, types::Chain, + constants::COMMIT_BOOST_DOMAIN, + pbs::{BlsPublicKey, BlsSignature}, + signature::verify_signed_message, + types::Chain, }; -pub trait ProxyId: AsRef<[u8]> + Debug + Clone + Copy + TreeHash + Display {} +pub trait ProxyId: Debug + Clone + TreeHash + Display { + fn to_bytes(&self) -> Vec; +} -impl ProxyId for Address {} +impl ProxyId for Address { + fn to_bytes(&self) -> Vec { + self.0.as_slice().to_vec() + } +} -impl ProxyId for BlsPublicKey {} +impl ProxyId for BlsPublicKey { + fn to_bytes(&self) -> Vec { + self.serialize().to_vec() + } +} // GENERIC PROXY DELEGATION -#[derive(Debug, Clone, Copy, Serialize, Deserialize, TreeHash)] +#[derive(Debug, Clone, Serialize, Deserialize, TreeHash)] pub struct ProxyDelegation { pub delegator: BlsPublicKey, pub proxy: T, @@ -40,7 +51,7 @@ impl fmt::Display for ProxyDelegation { } } -#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct SignedProxyDelegation { pub message: ProxyDelegation, /// Signature of message with the delegator keypair @@ -51,7 +62,7 @@ pub type SignedProxyDelegationBls = SignedProxyDelegation; pub type SignedProxyDelegationEcdsa = SignedProxyDelegation
; impl SignedProxyDelegation { - pub fn validate(&self, chain: Chain) -> Result<(), BlstErrorWrapper> { + pub fn validate(&self, chain: Chain) -> bool { verify_signed_message( chain, &self.message.delegator, diff --git a/crates/common/src/config/mux.rs b/crates/common/src/config/mux.rs index 77810ea8..682079be 100644 --- a/crates/common/src/config/mux.rs +++ b/crates/common/src/config/mux.rs @@ -7,7 +7,6 @@ use std::{ use alloy::{ primitives::{address, Address, U256}, providers::ProviderBuilder, - rpc::types::beacon::BlsPublicKey, sol, }; use eyre::{bail, ensure, Context}; @@ -16,7 +15,11 @@ use tracing::{debug, info}; use url::Url; use super::{load_optional_env_var, PbsConfig, RelayConfig, MUX_PATH_ENV}; -use crate::{config::remove_duplicate_keys, pbs::RelayClient, types::Chain}; +use crate::{ + config::remove_duplicate_keys, + pbs::{BlsPublicKey, RelayClient}, + types::Chain, +}; #[derive(Debug, Deserialize, Serialize)] pub struct PbsMuxes { @@ -93,8 +96,8 @@ impl PbsMuxes { let config = Arc::new(config); let runtime_config = RuntimeMuxConfig { id: mux.id, config, relays: relay_clients }; - for pubkey in mux.validator_pubkeys.iter() { - configs.insert(*pubkey, runtime_config.clone()); + for pubkey in mux.validator_pubkeys.into_iter() { + configs.insert(pubkey, runtime_config.clone()); } } @@ -254,7 +257,7 @@ async fn fetch_lido_registry_keys( debug!("fetching {total_keys} total keys"); const CALL_BATCH_SIZE: u64 = 250u64; - const BLS_PK_LEN: usize = BlsPublicKey::len_bytes(); + const BLS_PK_LEN: usize = 48; let mut keys = vec![]; let mut offset = 0; @@ -275,7 +278,10 @@ async fn fetch_lido_registry_keys( ); for chunk in pubkeys.chunks(BLS_PK_LEN) { - keys.push(BlsPublicKey::try_from(chunk)?); + keys.push( + BlsPublicKey::deserialize(chunk) + .map_err(|_| eyre::eyre!("invalid BLS public key"))?, + ); } offset += limit; @@ -319,10 +325,13 @@ async fn fetch_ssv_pubkeys( .json::() .await?; - pubkeys.extend(response.validators.iter().map(|v| v.pubkey).collect::>()); + let fetched = response.validators.len(); + pubkeys.extend( + response.validators.into_iter().map(|v| v.pubkey).collect::>(), + ); page += 1; - if response.validators.len() < MAX_PER_PAGE { + if fetched < MAX_PER_PAGE { ensure!( pubkeys.len() == response.pagination.total, "expected {} keys, got {}", @@ -383,8 +392,11 @@ mod tests { .pubkeys; let mut vec = vec![]; - for chunk in pubkeys.chunks(BlsPublicKey::len_bytes()) { - vec.push(BlsPublicKey::try_from(chunk)?); + for chunk in pubkeys.chunks(48) { + vec.push( + BlsPublicKey::deserialize(chunk) + .map_err(|_| eyre::eyre!("invalid BLS public key"))?, + ); } assert_eq!(vec.len(), LIMIT); diff --git a/crates/common/src/config/pbs.rs b/crates/common/src/config/pbs.rs index f41eef12..47362038 100644 --- a/crates/common/src/config/pbs.rs +++ b/crates/common/src/config/pbs.rs @@ -9,7 +9,6 @@ use std::{ use alloy::{ primitives::{utils::format_ether, U256}, providers::{Provider, ProviderBuilder}, - rpc::types::beacon::BlsPublicKey, }; use eyre::{ensure, Result}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; @@ -26,8 +25,8 @@ use crate::{ SIGNER_URL_ENV, }, pbs::{ - BuilderEventPublisher, DefaultTimeout, RelayClient, RelayEntry, DEFAULT_PBS_PORT, - LATE_IN_SLOT_TIME_MS, REGISTER_VALIDATOR_RETRY_LIMIT, + BlsPublicKey, BuilderEventPublisher, DefaultTimeout, RelayClient, RelayEntry, + DEFAULT_PBS_PORT, LATE_IN_SLOT_TIME_MS, REGISTER_VALIDATOR_RETRY_LIMIT, }, types::{Chain, Jwt, ModuleId}, utils::{ diff --git a/crates/common/src/config/utils.rs b/crates/common/src/config/utils.rs index d94fd826..84fd1a19 100644 --- a/crates/common/src/config/utils.rs +++ b/crates/common/src/config/utils.rs @@ -1,11 +1,10 @@ use std::{collections::HashMap, path::Path}; -use alloy::rpc::types::beacon::BlsPublicKey; use eyre::{bail, Context, Result}; use serde::de::DeserializeOwned; use super::JWTS_ENV; -use crate::types::ModuleId; +use crate::{pbs::BlsPublicKey, types::ModuleId}; pub fn load_env_var(env: &str) -> Result { std::env::var(env).wrap_err(format!("{env} is not set")) @@ -37,7 +36,7 @@ pub fn remove_duplicate_keys(keys: Vec) -> Vec { let mut key_set = std::collections::HashSet::new(); for key in keys { - if key_set.insert(key) { + if key_set.insert(key.clone()) { unique_keys.push(key); } } @@ -75,9 +74,9 @@ mod tests { #[test] fn test_remove_duplicate_keys() { - let key1 = BlsPublicKey::from([1; 48]); - let key2 = BlsPublicKey::from([2; 48]); - let keys = vec![key1, key2, key1]; + let key1 = BlsPublicKey::deserialize(&[1; 48]).unwrap(); + let key2 = BlsPublicKey::deserialize(&[2; 48]).unwrap(); + let keys = vec![key1.clone(), key2.clone(), key1.clone()]; let unique_keys = remove_duplicate_keys(keys); assert_eq!(unique_keys.len(), 2); diff --git a/crates/common/src/error.rs b/crates/common/src/error.rs deleted file mode 100644 index d34949ca..00000000 --- a/crates/common/src/error.rs +++ /dev/null @@ -1,58 +0,0 @@ -use std::fmt::{Display, Formatter}; - -use blst::BLST_ERROR; -use thiserror::Error; -#[derive(Debug, Error, PartialEq, Eq)] -pub enum BlstErrorWrapper { - BlstSuccess(BLST_ERROR), - BlstBadEncoding(BLST_ERROR), - BlstPointNotOnCurve(BLST_ERROR), - BlstPointNotInGroup(BLST_ERROR), - BlstAggrTypeMismatch(BLST_ERROR), - BlstVerifyFail(BLST_ERROR), - BlstPkIsInfinity(BLST_ERROR), - BlstBadScalar(BLST_ERROR), -} - -impl Display for BlstErrorWrapper { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - match self { - BlstErrorWrapper::BlstSuccess(_) => write!(f, "BLST_SUCCESS"), - BlstErrorWrapper::BlstBadEncoding(_) => write!(f, "BLST_BAD_ENCODING"), - BlstErrorWrapper::BlstPointNotOnCurve(_) => write!(f, "BLST_POINT_NOT_ON_CURVE"), - BlstErrorWrapper::BlstPointNotInGroup(_) => write!(f, "BLST_POINT_NOT_IN_GROUP"), - BlstErrorWrapper::BlstAggrTypeMismatch(_) => write!(f, "BLST_AGGR_TYPE_MISMATCH"), - BlstErrorWrapper::BlstVerifyFail(_) => write!(f, "BLST_VERIFY_FAIL"), - BlstErrorWrapper::BlstPkIsInfinity(_) => write!(f, "BLST_PK_IS_INFINITY"), - BlstErrorWrapper::BlstBadScalar(_) => write!(f, "BLST_BAD_SCALAR"), - } - } -} -impl From for BlstErrorWrapper { - fn from(value: BLST_ERROR) -> Self { - match value { - BLST_ERROR::BLST_SUCCESS => BlstErrorWrapper::BlstSuccess(BLST_ERROR::BLST_SUCCESS), - BLST_ERROR::BLST_BAD_ENCODING => { - BlstErrorWrapper::BlstBadEncoding(BLST_ERROR::BLST_BAD_ENCODING) - } - BLST_ERROR::BLST_POINT_NOT_ON_CURVE => { - BlstErrorWrapper::BlstPointNotOnCurve(BLST_ERROR::BLST_POINT_NOT_ON_CURVE) - } - BLST_ERROR::BLST_POINT_NOT_IN_GROUP => { - BlstErrorWrapper::BlstPointNotInGroup(BLST_ERROR::BLST_POINT_NOT_IN_GROUP) - } - BLST_ERROR::BLST_AGGR_TYPE_MISMATCH => { - BlstErrorWrapper::BlstAggrTypeMismatch(BLST_ERROR::BLST_AGGR_TYPE_MISMATCH) - } - BLST_ERROR::BLST_VERIFY_FAIL => { - BlstErrorWrapper::BlstVerifyFail(BLST_ERROR::BLST_VERIFY_FAIL) - } - BLST_ERROR::BLST_PK_IS_INFINITY => { - BlstErrorWrapper::BlstPkIsInfinity(BLST_ERROR::BLST_PK_IS_INFINITY) - } - BLST_ERROR::BLST_BAD_SCALAR => { - BlstErrorWrapper::BlstBadScalar(BLST_ERROR::BLST_BAD_SCALAR) - } - } - } -} diff --git a/crates/common/src/lib.rs b/crates/common/src/lib.rs index 5042061b..1fe1f26a 100644 --- a/crates/common/src/lib.rs +++ b/crates/common/src/lib.rs @@ -3,7 +3,6 @@ use std::time::Duration; pub mod commit; pub mod config; pub mod constants; -pub mod error; pub mod pbs; pub mod signature; pub mod signer; diff --git a/crates/common/src/pbs/error.rs b/crates/common/src/pbs/error.rs index 242cb90e..982d74f1 100644 --- a/crates/common/src/pbs/error.rs +++ b/crates/common/src/pbs/error.rs @@ -1,10 +1,7 @@ -use alloy::{ - primitives::{B256, U256}, - rpc::types::beacon::BlsPublicKey, -}; +use alloy::primitives::{B256, U256}; use thiserror::Error; -use crate::error::BlstErrorWrapper; +use crate::pbs::BlsPublicKey; #[derive(Debug, Error)] pub enum PbsError { @@ -83,8 +80,8 @@ pub enum ValidationError { #[error("empty tx root")] EmptyTxRoot, - #[error("failed signature verification: {0:?}")] - Sigverify(#[from] BlstErrorWrapper), + #[error("failed signature verification")] + Sigverify, #[error("wrong timestamp: expected {expected} got {got}")] TimestampMismatch { expected: u64, got: u64 }, diff --git a/crates/common/src/pbs/relay.rs b/crates/common/src/pbs/relay.rs index 1169175a..afb715de 100644 --- a/crates/common/src/pbs/relay.rs +++ b/crates/common/src/pbs/relay.rs @@ -1,9 +1,6 @@ use std::{str::FromStr, sync::Arc}; -use alloy::{ - primitives::{hex::FromHex, B256}, - rpc::types::beacon::BlsPublicKey, -}; +use alloy::primitives::B256; use eyre::WrapErr; use reqwest::header::{HeaderMap, HeaderName, HeaderValue}; use serde::{Deserialize, Serialize}; @@ -14,7 +11,7 @@ use super::{ error::PbsError, HEADER_VERSION_KEY, HEADER_VERSION_VALUE, }; -use crate::{config::RelayConfig, DEFAULT_REQUEST_TIMEOUT}; +use crate::{config::RelayConfig, pbs::BlsPublicKey, DEFAULT_REQUEST_TIMEOUT}; /// A parsed entry of the relay url in the format: scheme://pubkey@host #[derive(Debug, Clone)] @@ -43,7 +40,7 @@ impl<'de> Deserialize<'de> for RelayEntry { { let url = Url::deserialize(deserializer)?; let id = url.host().ok_or(serde::de::Error::custom("missing host"))?.to_string(); - let pubkey = BlsPublicKey::from_hex(url.username()) + let pubkey = BlsPublicKey::from_str(url.username()) .map_err(|_| serde::de::Error::custom("invalid BLS pubkey"))?; Ok(RelayEntry { pubkey, url, id }) @@ -84,8 +81,8 @@ impl RelayClient { Ok(Self { id: Arc::new(config.id().to_owned()), client, config: Arc::new(config) }) } - pub fn pubkey(&self) -> BlsPublicKey { - self.config.entry.pubkey + pub fn pubkey(&self) -> &BlsPublicKey { + &self.config.entry.pubkey } // URL builders @@ -108,8 +105,8 @@ impl RelayClient { pub fn get_header_url( &self, slot: u64, - parent_hash: B256, - validator_pubkey: BlsPublicKey, + parent_hash: &B256, + validator_pubkey: &BlsPublicKey, ) -> Result { self.builder_api_url(&format!("/header/{slot}/{parent_hash}/{validator_pubkey}")) } @@ -131,21 +128,19 @@ impl RelayClient { mod tests { use std::collections::HashMap; - use alloy::{ - primitives::{hex::FromHex, B256}, - rpc::types::beacon::BlsPublicKey, - }; + use alloy::{hex, primitives::B256}; use super::{RelayClient, RelayEntry}; - use crate::config::RelayConfig; + use crate::{config::RelayConfig, pbs::BlsPublicKey}; #[test] fn test_relay_entry() { - let s = "http://0xac6e77dfe25ecd6110b8e780608cce0dab71fdd5ebea22a16c0205200f2f8e2e3ad3b71d3499c54ad14d6c21b41a37ae@abc.xyz/"; + let pubkey = BlsPublicKey::deserialize(&hex!("0xac6e77dfe25ecd6110b8e780608cce0dab71fdd5ebea22a16c0205200f2f8e2e3ad3b71d3499c54ad14d6c21b41a37ae")).unwrap(); + let s = format!("http://{pubkey}@abc.xyz/"); let parsed = serde_json::from_str::(&format!("\"{s}\"")).unwrap(); - assert_eq!(parsed.pubkey, BlsPublicKey::from_hex("0xac6e77dfe25ecd6110b8e780608cce0dab71fdd5ebea22a16c0205200f2f8e2e3ad3b71d3499c54ad14d6c21b41a37ae").unwrap()); + assert_eq!(parsed.pubkey, pubkey); assert_eq!(parsed.url.as_str(), s); assert_eq!(parsed.id, "abc.xyz"); } @@ -154,7 +149,7 @@ mod tests { fn test_relay_url() { let slot = 0; let parent_hash = B256::ZERO; - let validator_pubkey = BlsPublicKey::ZERO; + let validator_pubkey = BlsPublicKey::deserialize(&hex!("0xac6e77dfe25ecd6110b8e780608cce0dab71fdd5ebea22a16c0205200f2f8e2e3ad3b71d3499c54ad14d6c21b41a37ae")).unwrap(); let expected = format!("http://0xa1cec75a3f0661e99299274182938151e8433c61a19222347ea1313d839229cb4ce4e3e5aa2bdeb71c8fcf1b084963c2@abc.xyz/eth/v1/builder/header/{slot}/{parent_hash}/{validator_pubkey}"); let relay_config = r#" @@ -166,7 +161,7 @@ mod tests { let relay = RelayClient::new(config).unwrap(); assert_eq!( - relay.get_header_url(slot, parent_hash, validator_pubkey).unwrap().to_string(), + relay.get_header_url(slot, &parent_hash, &validator_pubkey).unwrap().to_string(), expected ); @@ -179,7 +174,7 @@ mod tests { let relay = RelayClient::new(config).unwrap(); assert_eq!( - relay.get_header_url(slot, parent_hash, validator_pubkey).unwrap().to_string(), + relay.get_header_url(slot, &parent_hash, &validator_pubkey).unwrap().to_string(), expected ); } @@ -188,7 +183,7 @@ mod tests { fn test_relay_url_with_get_params() { let slot = 0; let parent_hash = B256::ZERO; - let validator_pubkey = BlsPublicKey::ZERO; + let validator_pubkey = BlsPublicKey::deserialize(&hex!("0xac6e77dfe25ecd6110b8e780608cce0dab71fdd5ebea22a16c0205200f2f8e2e3ad3b71d3499c54ad14d6c21b41a37ae")).unwrap(); // Note: HashMap iteration order is not guaranteed, so we can't predict the // exact order of parameters Instead of hard-coding the order, we'll // check that both parameters are present in the URL @@ -207,7 +202,7 @@ mod tests { config.get_params = Some(get_params); let relay = RelayClient::new(config).unwrap(); - let url = relay.get_header_url(slot, parent_hash, validator_pubkey).unwrap().to_string(); + let url = relay.get_header_url(slot, &parent_hash, &validator_pubkey).unwrap().to_string(); assert!(url.starts_with(&url_prefix)); assert!(url.contains("param1=value1")); assert!(url.contains("param2=value2")); diff --git a/crates/common/src/pbs/types/beacon_block.rs b/crates/common/src/pbs/types/beacon_block.rs index f377123a..77451f31 100644 --- a/crates/common/src/pbs/types/beacon_block.rs +++ b/crates/common/src/pbs/types/beacon_block.rs @@ -1,4 +1,4 @@ -use alloy::{primitives::B256, rpc::types::beacon::BlsSignature}; +use alloy::primitives::B256; use serde::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; @@ -6,8 +6,9 @@ use super::{ blinded_block_body::BlindedBeaconBlockBodyElectra, blobs_bundle::BlobsBundle, execution_payload::ExecutionPayload, spec::ElectraSpec, utils::VersionedResponse, }; +use crate::pbs::BlsSignature; -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] /// Sent to relays in submit_block pub struct SignedBlindedBeaconBlock { pub message: BlindedBeaconBlock, @@ -47,13 +48,7 @@ pub enum BlindedBeaconBlock { Electra(BlindedBeaconBlockElectra), } -impl Default for BlindedBeaconBlock { - fn default() -> Self { - Self::Electra(BlindedBeaconBlockElectra::default()) - } -} - -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] pub struct BlindedBeaconBlockElectra { #[serde(with = "serde_utils::quoted_u64")] pub slot: u64, diff --git a/crates/common/src/pbs/types/blinded_block_body.rs b/crates/common/src/pbs/types/blinded_block_body.rs index 966aa1e5..b09f3ab0 100644 --- a/crates/common/src/pbs/types/blinded_block_body.rs +++ b/crates/common/src/pbs/types/blinded_block_body.rs @@ -1,7 +1,4 @@ -use alloy::{ - primitives::{Address, B256}, - rpc::types::beacon::{BlsPublicKey, BlsSignature}, -}; +use alloy::primitives::{Address, B256}; use serde::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; use ssz_types::{typenum, BitList, BitVector, FixedVector, VariableList}; @@ -10,8 +7,9 @@ use super::{ execution_payload::ExecutionPayloadHeader, execution_requests::ExecutionRequests, kzg::KzgCommitments, spec::EthSpec, utils::*, }; +use crate::pbs::{BlsPublicKey, BlsSignature}; -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] #[serde(deny_unknown_fields)] pub struct BlindedBeaconBlockBodyElectra { pub randao_reveal: BlsSignature, @@ -49,13 +47,13 @@ pub struct BeaconBlockHeader { pub body_root: B256, } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] pub struct SignedBeaconBlockHeader { pub message: BeaconBlockHeader, pub signature: BlsSignature, } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] pub struct BlsToExecutionChange { #[serde(with = "serde_utils::quoted_u64")] pub validator_index: u64, @@ -63,25 +61,25 @@ pub struct BlsToExecutionChange { pub to_execution_address: Address, } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] pub struct SignedBlsToExecutionChange { pub message: BlsToExecutionChange, pub signature: BlsSignature, } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] pub struct ProposerSlashing { pub signed_header_1: SignedBeaconBlockHeader, pub signed_header_2: SignedBeaconBlockHeader, } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] pub struct AttesterSlashingElectra { pub attestation_1: IndexedAttestationElectra, pub attestation_2: IndexedAttestationElectra, } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] #[serde(bound = "T: EthSpec")] pub struct IndexedAttestationElectra { /// Lists validator registry indices, not committee indices. @@ -120,13 +118,13 @@ pub struct AttestationElectra { pub committee_bits: BitVector, } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] pub struct Deposit { pub proof: FixedVector, // put this in EthSpec? pub data: DepositData, } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] pub struct DepositData { pub pubkey: BlsPublicKey, pub withdrawal_credentials: B256, @@ -135,7 +133,7 @@ pub struct DepositData { pub signature: BlsSignature, } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] pub struct SignedVoluntaryExit { pub message: VoluntaryExit, pub signature: BlsSignature, @@ -150,7 +148,7 @@ pub struct VoluntaryExit { pub validator_index: u64, } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] #[serde(bound = "T: EthSpec")] pub struct SyncAggregate { pub sync_committee_bits: BitVector, diff --git a/crates/common/src/pbs/types/execution_requests.rs b/crates/common/src/pbs/types/execution_requests.rs index b84430bb..506c4468 100644 --- a/crates/common/src/pbs/types/execution_requests.rs +++ b/crates/common/src/pbs/types/execution_requests.rs @@ -1,13 +1,11 @@ -use alloy::{ - primitives::{Address, B256}, - rpc::types::beacon::{BlsPublicKey, BlsSignature}, -}; +use alloy::primitives::{Address, B256}; use serde::{Deserialize, Serialize}; use ssz_derive::{Decode, Encode}; use ssz_types::VariableList; use tree_hash_derive::TreeHash; use super::spec::EthSpec; +use crate::pbs::{BlsPublicKey, BlsSignature}; #[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode, TreeHash)] pub struct ExecutionRequests { @@ -16,7 +14,7 @@ pub struct ExecutionRequests { pub consolidations: VariableList, } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode, TreeHash)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash)] pub struct DepositRequest { pub pubkey: BlsPublicKey, pub withdrawal_credentials: B256, @@ -27,7 +25,7 @@ pub struct DepositRequest { pub index: u64, } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode, TreeHash)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash)] pub struct WithdrawalRequest { pub source_address: Address, pub validator_pubkey: BlsPublicKey, @@ -35,7 +33,7 @@ pub struct WithdrawalRequest { pub amount: u64, } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode, TreeHash)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash)] pub struct ConsolidationRequest { pub source_address: Address, pub source_pubkey: BlsPublicKey, diff --git a/crates/common/src/pbs/types/get_header.rs b/crates/common/src/pbs/types/get_header.rs index 76cde408..f53998c5 100644 --- a/crates/common/src/pbs/types/get_header.rs +++ b/crates/common/src/pbs/types/get_header.rs @@ -1,7 +1,4 @@ -use alloy::{ - primitives::{B256, U256}, - rpc::types::beacon::{BlsPublicKey, BlsSignature}, -}; +use alloy::primitives::{B256, U256}; use serde::{Deserialize, Serialize}; use ssz::{Decode, Encode}; use ssz_derive::{Decode, Encode}; @@ -11,8 +8,9 @@ use super::{ execution_payload::ExecutionPayloadHeader, execution_requests::ExecutionRequests, kzg::KzgCommitments, spec::ElectraSpec, utils::VersionedResponse, }; +use crate::pbs::{BlsPublicKey, BlsSignature}; -#[derive(Debug, Serialize, Deserialize, Clone, Copy)] +#[derive(Debug, Serialize, Deserialize, Clone)] pub struct GetHeaderParams { /// The slot to request the header for pub slot: u64, @@ -45,9 +43,9 @@ impl GetHeaderResponse { } } - pub fn pubkey(&self) -> BlsPublicKey { + pub fn pubkey(&self) -> &BlsPublicKey { match self { - VersionedResponse::Electra(data) => data.message.pubkey, + VersionedResponse::Electra(data) => &data.message.pubkey, } } @@ -69,20 +67,20 @@ impl GetHeaderResponse { } } - pub fn signautre(&self) -> BlsSignature { + pub fn signautre(&self) -> &BlsSignature { match self { - GetHeaderResponse::Electra(data) => data.signature, + GetHeaderResponse::Electra(data) => &data.signature, } } } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] pub struct SignedExecutionPayloadHeader { pub message: T, pub signature: BlsSignature, } -#[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode, TreeHash)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash)] pub struct ExecutionPayloadHeaderMessageElectra { pub header: ExecutionPayloadHeader, pub blob_kzg_commitments: KzgCommitments, @@ -177,8 +175,7 @@ mod tests { &parsed.message, &parsed.signature, APPLICATION_BUILDER_DOMAIN - ) - .is_ok()) + )) } #[test] diff --git a/crates/common/src/pbs/types/mod.rs b/crates/common/src/pbs/types/mod.rs index e22c4a2f..d96c577f 100644 --- a/crates/common/src/pbs/types/mod.rs +++ b/crates/common/src/pbs/types/mod.rs @@ -29,3 +29,7 @@ pub use kzg::{ }; pub use spec::{ElectraSpec, EthSpec}; pub use utils::VersionedResponse; + +pub type BlsPublicKey = lh_types::PublicKey; +pub type BlsSignature = lh_types::Signature; +pub type BlsSecretKey = lh_types::SecretKey; diff --git a/crates/common/src/signature.rs b/crates/common/src/signature.rs index e51e2291..5fc084aa 100644 --- a/crates/common/src/signature.rs +++ b/crates/common/src/signature.rs @@ -1,50 +1,49 @@ -use alloy::rpc::types::beacon::{constants::BLS_DST_SIG, BlsPublicKey, BlsSignature}; +use alloy::primitives::B256; use tree_hash::TreeHash; use tree_hash_derive::TreeHash; use crate::{ constants::{COMMIT_BOOST_DOMAIN, GENESIS_VALIDATORS_ROOT}, - error::BlstErrorWrapper, - signer::{verify_bls_signature, BlsSecretKey}, + pbs::{BlsPublicKey, BlsSecretKey, BlsSignature}, + signer::verify_bls_signature, types::Chain, }; -pub fn sign_message(secret_key: &BlsSecretKey, msg: &[u8]) -> BlsSignature { - let signature = secret_key.sign(msg, BLS_DST_SIG, &[]).to_bytes(); - BlsSignature::from_slice(&signature) +pub fn sign_message(secret_key: &BlsSecretKey, msg: B256) -> BlsSignature { + secret_key.sign(msg) } -pub fn compute_signing_root(object_root: [u8; 32], signing_domain: [u8; 32]) -> [u8; 32] { +pub fn compute_signing_root(object_root: B256, signing_domain: B256) -> B256 { #[derive(Default, Debug, TreeHash)] struct SigningData { - object_root: [u8; 32], - signing_domain: [u8; 32], + object_root: B256, + signing_domain: B256, } let signing_data = SigningData { object_root, signing_domain }; - signing_data.tree_hash_root().0 + signing_data.tree_hash_root() } // NOTE: this currently works only for builder domain signatures and // verifications // ref: https://github.com/ralexstokes/ethereum-consensus/blob/cf3c404043230559660810bc0c9d6d5a8498d819/ethereum-consensus/src/builder/mod.rs#L26-L29 -pub fn compute_domain(chain: Chain, domain_mask: [u8; 4]) -> [u8; 32] { +pub fn compute_domain(chain: Chain, domain_mask: [u8; 4]) -> B256 { #[derive(Debug, TreeHash)] struct ForkData { fork_version: [u8; 4], - genesis_validators_root: [u8; 32], + genesis_validators_root: B256, } let mut domain = [0u8; 32]; domain[..4].copy_from_slice(&domain_mask); let fork_version = chain.genesis_fork_version(); - let fd = ForkData { fork_version, genesis_validators_root: GENESIS_VALIDATORS_ROOT }; + let fd = ForkData { fork_version, genesis_validators_root: GENESIS_VALIDATORS_ROOT.into() }; let fork_data_root = fd.tree_hash_root(); domain[4..].copy_from_slice(&fork_data_root[..28]); - domain + domain.into() } pub fn verify_signed_message( @@ -53,11 +52,11 @@ pub fn verify_signed_message( msg: &T, signature: &BlsSignature, domain_mask: [u8; 4], -) -> Result<(), BlstErrorWrapper> { +) -> bool { let domain = compute_domain(chain, domain_mask); - let signing_root = compute_signing_root(msg.tree_hash_root().0, domain); + let signing_root = compute_signing_root(msg.tree_hash_root(), domain); - verify_bls_signature(pubkey, &signing_root, signature) + verify_bls_signature(pubkey, signing_root, signature) } pub fn sign_builder_message( @@ -65,27 +64,27 @@ pub fn sign_builder_message( secret_key: &BlsSecretKey, msg: &impl TreeHash, ) -> BlsSignature { - sign_builder_root(chain, secret_key, msg.tree_hash_root().0) + sign_builder_root(chain, secret_key, msg.tree_hash_root()) } pub fn sign_builder_root( chain: Chain, secret_key: &BlsSecretKey, - object_root: [u8; 32], + object_root: B256, ) -> BlsSignature { let domain = chain.builder_domain(); let signing_root = compute_signing_root(object_root, domain); - sign_message(secret_key, &signing_root) + sign_message(secret_key, signing_root) } pub fn sign_commit_boost_root( chain: Chain, secret_key: &BlsSecretKey, - object_root: [u8; 32], + object_root: B256, ) -> BlsSignature { let domain = compute_domain(chain, COMMIT_BOOST_DOMAIN); let signing_root = compute_signing_root(object_root, domain); - sign_message(secret_key, &signing_root) + sign_message(secret_key, signing_root) } #[cfg(test)] diff --git a/crates/common/src/signer/loader.rs b/crates/common/src/signer/loader.rs index d678795e..a5855f42 100644 --- a/crates/common/src/signer/loader.rs +++ b/crates/common/src/signer/loader.rs @@ -8,9 +8,8 @@ use aes::{ cipher::{KeyIvInit, StreamCipher}, Aes128, }; -use alloy::{primitives::hex::FromHex, rpc::types::beacon::BlsPublicKey}; -use eth2_keystore::{json_keystore::JsonKeystore, Keystore}; use eyre::{eyre, Context}; +use lh_eth2_keystore::{json_keystore::JsonKeystore, Keystore}; use pbkdf2::{hmac, pbkdf2}; use rayon::prelude::*; use serde::{de, Deserialize, Deserializer, Serialize}; @@ -20,6 +19,7 @@ use unicode_normalization::UnicodeNormalization; use super::{BlsSigner, EcdsaSigner, PrysmDecryptedKeystore, PrysmKeystore}; use crate::{ config::{load_env_var, SIGNER_DIR_KEYS_ENV, SIGNER_DIR_SECRETS_ENV, SIGNER_KEYS_ENV}, + pbs::BlsPublicKey, signer::ConsensusSigner, }; @@ -124,7 +124,12 @@ fn load_from_lighthouse_format( } let maybe_pubkey = path.file_name().and_then(|d| d.to_str())?; - let Ok(pubkey) = BlsPublicKey::from_hex(maybe_pubkey) else { + let Ok(decoded) = alloy::primitives::hex::decode(maybe_pubkey) else { + warn!("Invalid pubkey: {}", maybe_pubkey); + return None + }; + + let Ok(pubkey) = BlsPublicKey::deserialize(&decoded) else { warn!("Invalid pubkey: {}", maybe_pubkey); return None }; @@ -290,7 +295,7 @@ pub fn load_ecdsa_signer(keys_path: PathBuf, secrets_path: PathBuf) -> eyre::Res let key_reader = std::io::BufReader::new(key_file); let keystore: JsonKeystore = serde_json::from_reader(key_reader)?; let password = std::fs::read(secrets_path)?; - let decrypted_password = eth2_keystore::decrypt(&password, &keystore.crypto) + let decrypted_password = lh_eth2_keystore::decrypt(&password, &keystore.crypto) .map_err(|_| eyre::eyre!("Error decrypting ECDSA keystore"))?; EcdsaSigner::new_from_bytes(decrypted_password.as_bytes()) @@ -299,12 +304,15 @@ pub fn load_ecdsa_signer(keys_path: PathBuf, secrets_path: PathBuf) -> eyre::Res #[cfg(test)] mod tests { - use alloy::{hex, primitives::FixedBytes}; + use alloy::hex; use super::{load_from_lighthouse_format, load_from_lodestar_format, FileKey}; - use crate::signer::{ - loader::{load_from_prysm_format, load_from_teku_format}, - BlsPublicKey, BlsSigner, + use crate::{ + pbs::BlsPublicKey, + signer::{ + loader::{load_from_prysm_format, load_from_teku_format}, + BlsSigner, + }, }; #[test] @@ -325,12 +333,12 @@ mod tests { fn test_correct_load(signers: Vec) { assert_eq!(signers.len(), 2); - assert!(signers.iter().any(|s| s.pubkey() == BlsPublicKey::from(FixedBytes::new( + assert!(signers.iter().any(|s| s.pubkey() == BlsPublicKey::deserialize(& hex!("883827193f7627cd04e621e1e8d56498362a52b2a30c9a1c72036eb935c4278dee23d38a24d2f7dda62689886f0c39f4") - )))); - assert!(signers.iter().any(|s| s.pubkey() == BlsPublicKey::from(FixedBytes::new( + ).unwrap())); + assert!(signers.iter().any(|s| s.pubkey() == BlsPublicKey::deserialize(& hex!("b3a22e4a673ac7a153ab5b3c17a4dbef55f7e47210b20c0cbb0e66df5b36bb49ef808577610b034172e955d2312a61b9") - )))); + ).unwrap())); } #[test] @@ -381,9 +389,9 @@ mod tests { let signers = result.unwrap(); assert_eq!(signers.len(), 1); - assert!(signers[0].pubkey() == BlsPublicKey::from(FixedBytes::new( + assert!(signers[0].pubkey() == BlsPublicKey::deserialize(& hex!("883827193f7627cd04e621e1e8d56498362a52b2a30c9a1c72036eb935c4278dee23d38a24d2f7dda62689886f0c39f4") - ))); + ).unwrap()); let result = load_from_lodestar_format( "../../tests/data/keystores/teku-keys/".into(), @@ -395,8 +403,8 @@ mod tests { let signers = result.unwrap(); assert_eq!(signers.len(), 1); - assert!(signers[0].pubkey() == BlsPublicKey::from(FixedBytes::new( + assert!(signers[0].pubkey() == BlsPublicKey::deserialize(& hex!("b3a22e4a673ac7a153ab5b3c17a4dbef55f7e47210b20c0cbb0e66df5b36bb49ef808577610b034172e955d2312a61b9") - ))); + ).unwrap()); } } diff --git a/crates/common/src/signer/schemes/bls.rs b/crates/common/src/signer/schemes/bls.rs index f133b2bc..3018bc4a 100644 --- a/crates/common/src/signer/schemes/bls.rs +++ b/crates/common/src/signer/schemes/bls.rs @@ -1,16 +1,12 @@ -use alloy::rpc::types::beacon::constants::BLS_DST_SIG; -pub use alloy::rpc::types::beacon::BlsSignature; -use blst::BLST_ERROR; +use alloy::primitives::B256; use tree_hash::TreeHash; use crate::{ - error::BlstErrorWrapper, signature::sign_commit_boost_root, types::Chain, - utils::blst_pubkey_to_alloy, + pbs::{BlsPublicKey, BlsSecretKey, BlsSignature}, + signature::sign_commit_boost_root, + types::Chain, }; -pub type BlsSecretKey = blst::min_pk::SecretKey; -pub type BlsPublicKey = alloy::rpc::types::beacon::BlsPublicKey; - #[derive(Clone)] pub enum BlsSigner { Local(BlsSecretKey), @@ -22,61 +18,38 @@ impl BlsSigner { } pub fn new_from_bytes(bytes: &[u8]) -> eyre::Result { - let secret = BlsSecretKey::from_bytes(bytes).map_err(BlstErrorWrapper::from)?; + let secret = + BlsSecretKey::deserialize(bytes).map_err(|_| eyre::eyre!("invalid secret key"))?; Ok(Self::Local(secret)) } pub fn pubkey(&self) -> BlsPublicKey { match self { - BlsSigner::Local(secret) => blst_pubkey_to_alloy(&secret.sk_to_pk()), + BlsSigner::Local(secret) => secret.public_key(), } } pub fn secret(&self) -> [u8; 32] { match self { - BlsSigner::Local(secret) => secret.clone().to_bytes(), + BlsSigner::Local(secret) => secret.serialize().as_bytes().try_into().unwrap(), } } - pub async fn sign(&self, chain: Chain, object_root: [u8; 32]) -> BlsSignature { + pub async fn sign(&self, chain: Chain, object_root: B256) -> BlsSignature { match self { BlsSigner::Local(sk) => sign_commit_boost_root(chain, sk, object_root), } } pub async fn sign_msg(&self, chain: Chain, msg: &impl TreeHash) -> BlsSignature { - self.sign(chain, msg.tree_hash_root().0).await + self.sign(chain, msg.tree_hash_root()).await } } pub fn random_secret() -> BlsSecretKey { - use rand::RngCore; - - let mut rng = rand::rng(); - let mut ikm = [0u8; 32]; - rng.fill_bytes(&mut ikm); - - match BlsSecretKey::key_gen(&ikm, &[]) { - Ok(key) => key, - // Key material is always valid (32 `u8`s), so `key_gen` can't return Err. - Err(_) => unreachable!(), - } + BlsSecretKey::random() } -pub fn verify_bls_signature( - pubkey: &BlsPublicKey, - msg: &[u8], - signature: &BlsSignature, -) -> Result<(), BlstErrorWrapper> { - use crate::utils::{alloy_pubkey_to_blst, alloy_sig_to_blst}; - - let pubkey = alloy_pubkey_to_blst(pubkey)?; - let signature = alloy_sig_to_blst(signature)?; - - let res = signature.verify(true, msg, BLS_DST_SIG, &[], &pubkey, true); - if res == BLST_ERROR::BLST_SUCCESS { - Ok(()) - } else { - Err(res.into()) - } +pub fn verify_bls_signature(pubkey: &BlsPublicKey, msg: B256, signature: &BlsSignature) -> bool { + signature.verify(pubkey, msg) } diff --git a/crates/common/src/signer/schemes/ecdsa.rs b/crates/common/src/signer/schemes/ecdsa.rs index 612df5e3..4f7d9892 100644 --- a/crates/common/src/signer/schemes/ecdsa.rs +++ b/crates/common/src/signer/schemes/ecdsa.rs @@ -1,7 +1,7 @@ use std::{ops::Deref, str::FromStr}; use alloy::{ - primitives::{Address, PrimitiveSignature}, + primitives::{Address, PrimitiveSignature, B256}, signers::{local::PrivateKeySigner, SignerSync}, }; use eyre::ensure; @@ -86,7 +86,7 @@ impl EcdsaSigner { pub async fn sign( &self, chain: Chain, - object_root: [u8; 32], + object_root: B256, ) -> Result { match self { EcdsaSigner::Local(sk) => { @@ -102,7 +102,7 @@ impl EcdsaSigner { chain: Chain, msg: &impl TreeHash, ) -> Result { - self.sign(chain, msg.tree_hash_root().0).await + self.sign(chain, msg.tree_hash_root()).await } } @@ -128,7 +128,7 @@ mod test { let pk = bytes!("88bcd6672d95bcba0d52a3146494ed4d37675af4ed2206905eb161aa99a6c0d1"); let signer = EcdsaSigner::new_from_bytes(&pk).unwrap(); - let object_root = [1; 32]; + let object_root = B256::from([1; 32]); let signature = signer.sign(Chain::Holesky, object_root).await.unwrap(); let domain = compute_domain(Chain::Holesky, COMMIT_BOOST_DOMAIN); diff --git a/crates/common/src/signer/store.rs b/crates/common/src/signer/store.rs index bd23c120..b1705597 100644 --- a/crates/common/src/signer/store.rs +++ b/crates/common/src/signer/store.rs @@ -8,10 +8,10 @@ use std::{ use alloy::{ hex, - primitives::{Address, Bytes, FixedBytes}, - rpc::types::beacon::constants::BLS_SIGNATURE_BYTES_LEN, + primitives::{Address, Bytes}, }; -use eth2_keystore::{ +use eyre::{Context, OptionExt}; +use lh_eth2_keystore::{ default_kdf, json_keystore::{ Aes128Ctr, ChecksumModule, Cipher, CipherModule, Crypto, JsonKeystore, KdfModule, @@ -19,7 +19,6 @@ use eth2_keystore::{ }, Uuid, IV_SIZE, SALT_SIZE, }; -use eyre::{Context, OptionExt}; use rand::Rng; use serde::{Deserialize, Serialize}; use tracing::{trace, warn}; @@ -28,9 +27,8 @@ use super::{load_bls_signer, load_ecdsa_signer}; use crate::{ commit::request::{EncryptionScheme, ProxyDelegation, ProxyId, SignedProxyDelegation}, config::{load_env_var, PROXY_DIR_ENV, PROXY_DIR_KEYS_ENV, PROXY_DIR_SECRETS_ENV}, - signer::{ - BlsProxySigner, BlsPublicKey, BlsSigner, EcdsaProxySigner, EcdsaSigner, ProxySigners, - }, + pbs::{BlsPublicKey, BlsSignature}, + signer::{BlsProxySigner, BlsSigner, EcdsaProxySigner, EcdsaSigner, ProxySigners}, types::ModuleId, }; @@ -90,7 +88,7 @@ impl ProxyStore { .join("bls") .join(proxy.signer.pubkey().to_string()); let secret = Bytes::from(proxy.signer.secret()); - let to_store = KeyAndDelegation { secret, delegation: proxy.delegation }; + let to_store = KeyAndDelegation { secret, delegation: proxy.delegation.clone() }; let content = serde_json::to_vec(&to_store)?; if let Some(parent) = file_path.parent() { @@ -103,7 +101,7 @@ impl ProxyStore { ProxyStore::ERC2335 { keys_path, secrets_path } => { store_erc2335_key( module_id, - proxy.delegation, + proxy.delegation.clone(), proxy.secret().to_vec(), keys_path, secrets_path, @@ -127,7 +125,7 @@ impl ProxyStore { .join("ecdsa") .join(proxy.signer.address().to_string()); let secret = Bytes::from(proxy.signer.secret()); - let to_store = KeyAndDelegation { secret, delegation: proxy.delegation }; + let to_store = KeyAndDelegation { secret, delegation: proxy.delegation.clone() }; let content = serde_json::to_vec(&to_store)?; if let Some(parent) = file_path.parent() { @@ -140,7 +138,7 @@ impl ProxyStore { ProxyStore::ERC2335 { keys_path, secrets_path } => { store_erc2335_key( module_id, - proxy.delegation, + proxy.delegation.clone(), proxy.secret(), keys_path, secrets_path, @@ -230,7 +228,9 @@ impl ProxyStore { delegation: key_and_delegation.delegation, }; - proxy_signers.bls_signers.insert(pubkey, proxy_signer); + proxy_signers + .bls_signers + .insert(pubkey.clone(), proxy_signer); bls_map.entry(module_id.clone()).or_default().push(pubkey); } } @@ -277,20 +277,24 @@ impl ProxyStore { for entry in std::fs::read_dir(keys_path)? { let entry = entry?; let consensus_key_path = entry.path(); - let consensus_pubkey = - match FixedBytes::from_str(&entry.file_name().to_string_lossy()) { - Ok(bytes) => BlsPublicKey::from(bytes), - Err(e) => { - warn!("Failed to parse consensus pubkey: {e}"); - continue; - } - }; + let Ok(consensus_key_str) = + hex::decode(entry.file_name().to_string_lossy().as_ref()) + else { + warn!("Failed to parse consensus pubkey: {consensus_key_path:?}"); + continue; + }; + + let Ok(consensus_pubkey) = BlsPublicKey::deserialize(&consensus_key_str) else { + warn!("Failed to parse consensus pubkey: {consensus_key_path:?}"); + continue; + }; if !consensus_key_path.is_dir() { warn!("{consensus_key_path:?} is not a directory"); continue; } + let consensus_pubkey_str = consensus_pubkey.to_string(); for entry in std::fs::read_dir(&consensus_key_path)? { let entry = entry?; let module_path = entry.path(); @@ -319,30 +323,42 @@ impl ProxyStore { let signer = load_bls_signer( path, secrets_path - .join(consensus_pubkey.to_string()) + .join(consensus_pubkey_str.clone()) .join(&module_id) .join("bls") .join(name), ) .map_err(|e| eyre::eyre!("Error loading BLS signer: {e}"))?; - let delegation_signature = match std::fs::read_to_string( - bls_path.join(format!("{name}.sig")), - ) { - Ok(sig) => { - FixedBytes::::from_str(&sig)? - } - Err(e) => { - warn!("Failed to read delegation signature: {e}"); - continue; - } + let delegation_signature_path = + bls_path.join(format!("{name}.sig")); + + let Ok(delegation_signature) = + std::fs::read_to_string(&delegation_signature_path) + else { + warn!("Failed to read delegation signature: {delegation_signature_path:?}"); + continue; + }; + + let Ok(delegation_signature) = + alloy::primitives::hex::decode(delegation_signature) + else { + warn!("Failed to parse delegation signature: {delegation_signature_path:?}"); + continue; + }; + + let Ok(delegation_signature) = + BlsSignature::deserialize(&delegation_signature) + else { + warn!("Failed to parse delegation signature: {delegation_signature_path:?}"); + continue; }; let proxy_signer = BlsProxySigner { signer: signer.clone(), delegation: SignedProxyDelegation { message: ProxyDelegation { - delegator: consensus_pubkey, + delegator: consensus_pubkey.clone(), proxy: signer.pubkey(), }, signature: delegation_signature, @@ -375,28 +391,41 @@ impl ProxyStore { let signer = load_ecdsa_signer( path, secrets_path - .join(consensus_pubkey.to_string()) + .join(consensus_pubkey_str.clone()) .join(&module_id) .join("ecdsa") .join(name), )?; - let delegation_signature = match std::fs::read_to_string( - ecdsa_path.join(format!("{name}.sig")), - ) { - Ok(sig) => { - FixedBytes::::from_str(&sig)? - } - Err(e) => { - warn!("Failed to read delegation signature: {e}",); - continue; - } + + let delegation_signature_path = + ecdsa_path.join(format!("{name}.sig")); + + let Ok(delegation_signature) = + std::fs::read_to_string(&delegation_signature_path) + else { + warn!("Failed to read delegation signature: {delegation_signature_path:?}"); + continue; + }; + + let Ok(delegation_signature) = + alloy::primitives::hex::decode(delegation_signature) + else { + warn!("Failed to parse delegation signature: {delegation_signature_path:?}"); + continue; + }; + + let Ok(delegation_signature) = + BlsSignature::deserialize(&delegation_signature) + else { + warn!("Failed to parse delegation signature: {delegation_signature_path:?}"); + continue; }; let proxy_signer = EcdsaProxySigner { signer: signer.clone(), delegation: SignedProxyDelegation { message: ProxyDelegation { - delegator: consensus_pubkey, + delegator: consensus_pubkey.clone(), proxy: signer.address(), }, signature: delegation_signature, @@ -426,7 +455,7 @@ fn store_erc2335_key( secrets_path: &Path, scheme: EncryptionScheme, ) -> eyre::Result<()> { - let proxy_delegation = delegation.message.proxy; + let proxy_delegation = delegation.message.proxy.clone(); let password_bytes: [u8; 32] = rand::rng().random(); let password = hex::encode(password_bytes); @@ -455,7 +484,7 @@ fn store_erc2335_key( let kdf = default_kdf(salt.to_vec()); let cipher = Cipher::Aes128Ctr(Aes128Ctr { iv: iv.to_vec().into() }); let (cipher_text, checksum) = - eth2_keystore::encrypt(&secret, password.as_bytes(), &kdf, &cipher) + lh_eth2_keystore::encrypt(&secret, password.as_bytes(), &kdf, &cipher) .map_err(|_| eyre::eyre!("Error encrypting key"))?; let keystore = JsonKeystore { @@ -463,11 +492,11 @@ fn store_erc2335_key( kdf: KdfModule { function: kdf.function(), params: kdf, - message: eth2_keystore::json_keystore::EmptyString, + message: lh_eth2_keystore::json_keystore::EmptyString, }, checksum: ChecksumModule { function: Sha256Checksum::function(), - params: eth2_keystore::json_keystore::EmptyMap, + params: lh_eth2_keystore::json_keystore::EmptyMap, message: checksum.to_vec().into(), }, cipher: CipherModule { @@ -478,8 +507,8 @@ fn store_erc2335_key( }, uuid: Uuid::new_v4(), path: None, - pubkey: alloy::hex::encode(delegation.message.proxy), - version: eth2_keystore::json_keystore::Version::V4, + pubkey: alloy::hex::encode(delegation.message.proxy.to_bytes()), + version: lh_eth2_keystore::json_keystore::Version::V4, description: Some(delegation.message.proxy.to_string()), name: None, }; @@ -498,7 +527,6 @@ fn store_erc2335_key( #[cfg(test)] mod test { - use hex::FromHex; use tree_hash::TreeHash; use super::*; @@ -532,8 +560,8 @@ mod test { delegator: consensus_signer.pubkey(), proxy: proxy_signer.pubkey(), }; - let signature = consensus_signer.sign(Chain::Mainnet, message.tree_hash_root().0).await; - let delegation = SignedProxyDelegationBls { signature, message }; + let signature = consensus_signer.sign(Chain::Mainnet, message.tree_hash_root()).await; + let delegation = SignedProxyDelegationBls { signature: signature.clone(), message }; let proxy_signer = BlsProxySigner { signer: proxy_signer, delegation }; store.store_proxy_bls(&module_id, &proxy_signer).unwrap(); @@ -563,9 +591,10 @@ mod test { assert_eq!(keystore.pubkey, proxy_signer.pubkey().to_string().trim_start_matches("0x")); - let sig = FixedBytes::from_hex(std::fs::read_to_string(sig_path).unwrap()); - assert!(sig.is_ok()); - assert_eq!(sig.unwrap(), signature); + let sig = hex::decode(std::fs::read_to_string(sig_path).unwrap()).unwrap(); + let sig = BlsSignature::deserialize(&sig).unwrap(); + + assert_eq!(sig, signature); } #[test] @@ -583,16 +612,17 @@ mod test { assert_eq!(proxy_signers.bls_signers.len(), 1); assert_eq!(proxy_signers.ecdsa_signers.len(), 0); - let proxy_key = BlsPublicKey::from( - FixedBytes::from_hex( + let proxy_key = BlsPublicKey::deserialize( + &hex::decode( "a77084280678d9f1efe4ef47a3d62af27872ce82db19a35ee012c4fd5478e6b1123b8869032ba18b2383e8873294f0ba" ).unwrap() - ); - let consensus_key = BlsPublicKey::from( - FixedBytes::from_hex( + ).unwrap(); + + let consensus_key = BlsPublicKey::deserialize( + &hex::decode( "ac5e059177afc33263e95d0be0690138b9a1d79a6e19018086a0362e0c30a50bf9e05a08cb44785724d0b2718c5c7118" ).unwrap() - ); + ).unwrap(); let proxy_signer = proxy_signers.bls_signers.get(&proxy_key); @@ -601,13 +631,16 @@ mod test { assert_eq!( proxy_signer.delegation.signature, - FixedBytes::from_hex( - std::fs::read_to_string( - keys_path - .join(consensus_key.to_string()) - .join("TEST_MODULE") - .join("bls") - .join(format!("{proxy_key}.sig")) + BlsSignature::deserialize( + &hex::decode( + std::fs::read_to_string( + keys_path + .join(consensus_key.clone().to_string()) + .join("TEST_MODULE") + .join("bls") + .join(format!("{proxy_key}.sig")) + ) + .unwrap() ) .unwrap() ) @@ -645,7 +678,7 @@ mod test { delegator: consensus_signer.pubkey(), proxy: proxy_signer.pubkey(), }; - let signature = consensus_signer.sign(Chain::Mainnet, message.tree_hash_root().0).await; + let signature = consensus_signer.sign(Chain::Mainnet, message.tree_hash_root()).await; let delegation = SignedProxyDelegationBls { signature, message }; let proxy_signer = BlsProxySigner { signer: proxy_signer, delegation }; @@ -668,13 +701,16 @@ mod test { assert_eq!( loaded_proxy_signer.delegation.signature, - FixedBytes::from_hex( - std::fs::read_to_string( - keys_path - .join(consensus_signer.pubkey().to_string()) - .join("TEST_MODULE") - .join("bls") - .join(format!("{}.sig", proxy_signer.pubkey().to_string())) + BlsSignature::deserialize( + &hex::decode( + std::fs::read_to_string( + keys_path + .join(consensus_signer.pubkey().to_string()) + .join("TEST_MODULE") + .join("bls") + .join(format!("{}.sig", proxy_signer.pubkey().to_string())) + ) + .unwrap() ) .unwrap() ) diff --git a/crates/common/src/signer/types.rs b/crates/common/src/signer/types.rs index da36af5d..581518c4 100644 --- a/crates/common/src/signer/types.rs +++ b/crates/common/src/signer/types.rs @@ -8,9 +8,10 @@ use serde::{ Deserialize, Deserializer, }; -use super::{BlsPublicKey, EcdsaSigner}; +use super::EcdsaSigner; use crate::{ commit::request::{SignedProxyDelegationBls, SignedProxyDelegationEcdsa}, + pbs::BlsPublicKey, signer::BlsSigner, }; diff --git a/crates/common/src/types.rs b/crates/common/src/types.rs index 5293a789..b1060a87 100644 --- a/crates/common/src/types.rs +++ b/crates/common/src/types.rs @@ -1,6 +1,6 @@ use std::path::PathBuf; -use alloy::primitives::{hex, Bytes}; +use alloy::primitives::{hex, Bytes, B256}; use derive_more::{Deref, Display, From, Into}; use eyre::{bail, Context}; use serde::{Deserialize, Serialize}; @@ -78,13 +78,13 @@ impl Chain { } } - pub fn builder_domain(&self) -> [u8; 32] { + pub fn builder_domain(&self) -> B256 { match self { - Chain::Mainnet => KnownChain::Mainnet.builder_domain(), - Chain::Holesky => KnownChain::Holesky.builder_domain(), - Chain::Sepolia => KnownChain::Sepolia.builder_domain(), - Chain::Helder => KnownChain::Helder.builder_domain(), - Chain::Hoodi => KnownChain::Hoodi.builder_domain(), + Chain::Mainnet => KnownChain::Mainnet.builder_domain().into(), + Chain::Holesky => KnownChain::Holesky.builder_domain().into(), + Chain::Sepolia => KnownChain::Sepolia.builder_domain().into(), + Chain::Helder => KnownChain::Helder.builder_domain().into(), + Chain::Hoodi => KnownChain::Hoodi.builder_domain().into(), Chain::Custom { .. } => compute_domain(*self, APPLICATION_BUILDER_DOMAIN), } } diff --git a/crates/common/src/utils.rs b/crates/common/src/utils.rs index a1dcb7cb..8c5c1721 100644 --- a/crates/common/src/utils.rs +++ b/crates/common/src/utils.rs @@ -3,12 +3,8 @@ use std::{ time::{SystemTime, UNIX_EPOCH}, }; -use alloy::{ - primitives::U256, - rpc::types::beacon::{BlsPublicKey, BlsSignature}, -}; +use alloy::primitives::U256; use axum::http::HeaderValue; -use blst::min_pk::{PublicKey, Signature}; use rand::{distr::Alphanumeric, Rng}; use reqwest::header::HeaderMap; use serde::{de::DeserializeOwned, Serialize}; @@ -264,20 +260,6 @@ pub fn print_logo() { ) } -// Crypto conversions - -pub fn alloy_pubkey_to_blst(pubkey: &BlsPublicKey) -> Result { - PublicKey::key_validate(&pubkey.0) -} - -pub fn alloy_sig_to_blst(signature: &BlsSignature) -> Result { - Signature::from_bytes(&signature.0) -} - -pub fn blst_pubkey_to_alloy(pubkey: &PublicKey) -> BlsPublicKey { - BlsPublicKey::from_slice(&pubkey.to_bytes()) -} - /// Create a JWT for the given module id with expiration pub fn create_jwt(module_id: &ModuleId, secret: &str) -> eyre::Result { jsonwebtoken::encode( diff --git a/crates/pbs/Cargo.toml b/crates/pbs/Cargo.toml index ad747f9d..4cc3d2b2 100644 --- a/crates/pbs/Cargo.toml +++ b/crates/pbs/Cargo.toml @@ -10,7 +10,6 @@ alloy.workspace = true async-trait.workspace = true axum.workspace = true axum-extra.workspace = true -blst.workspace = true cb-common.workspace = true cb-metrics.workspace = true eyre.workspace = true diff --git a/crates/pbs/src/mev_boost/get_header.rs b/crates/pbs/src/mev_boost/get_header.rs index ce591ba1..fc04c534 100644 --- a/crates/pbs/src/mev_boost/get_header.rs +++ b/crates/pbs/src/mev_boost/get_header.rs @@ -6,18 +6,17 @@ use std::{ use alloy::{ primitives::{utils::format_ether, B256, U256}, providers::Provider, - rpc::types::{beacon::BlsPublicKey, Block}, + rpc::types::Block, }; use axum::http::{HeaderMap, HeaderValue}; use cb_common::{ constants::APPLICATION_BUILDER_DOMAIN, pbs::{ error::{PbsError, ValidationError}, - GetHeaderParams, GetHeaderResponse, RelayClient, VersionedResponse, EMPTY_TX_ROOT_HASH, - HEADER_START_TIME_UNIX_MS, + BlsPublicKey, BlsSignature, GetHeaderParams, GetHeaderResponse, RelayClient, + VersionedResponse, EMPTY_TX_ROOT_HASH, HEADER_START_TIME_UNIX_MS, }, signature::verify_signed_message, - signer::BlsSignature, types::Chain, utils::{get_user_agent_with_version, ms_into_slot, timestamp_of_slot_start_sec, utcnow_ms}, }; @@ -87,7 +86,7 @@ pub async fn get_header( for relay in relays.iter() { handles.push( send_timed_get_header( - params, + params.clone(), relay.clone(), state.config.chain, send_headers.clone(), @@ -163,7 +162,7 @@ async fn send_timed_get_header( mut timeout_left_ms: u64, validation: ValidationContext, ) -> Result, PbsError> { - let url = relay.get_header_url(params.slot, params.parent_hash, params.pubkey)?; + let url = relay.get_header_url(params.slot, ¶ms.parent_hash, ¶ms.pubkey)?; if relay.config.enable_timing_games { if let Some(target_ms) = relay.config.target_first_request_ms { @@ -194,6 +193,7 @@ async fn send_timed_get_header( ); loop { + let params = params.clone(); handles.push(tokio::spawn( send_one_get_header( params, @@ -383,7 +383,7 @@ async fn send_one_get_header( validate_signature( chain, relay.pubkey(), - res.message.pubkey, + &res.message.pubkey, &res.message, &res.signature, )?; @@ -453,26 +453,27 @@ fn validate_header_data( fn validate_signature( chain: Chain, - expected_relay_pubkey: BlsPublicKey, - received_relay_pubkey: BlsPublicKey, + expected_relay_pubkey: &BlsPublicKey, + received_relay_pubkey: &BlsPublicKey, message: &T, signature: &BlsSignature, ) -> Result<(), ValidationError> { if expected_relay_pubkey != received_relay_pubkey { return Err(ValidationError::PubkeyMismatch { - expected: expected_relay_pubkey, - got: received_relay_pubkey, + expected: expected_relay_pubkey.clone(), + got: received_relay_pubkey.clone(), }); } - verify_signed_message( + if !verify_signed_message( chain, &received_relay_pubkey, &message, signature, APPLICATION_BUILDER_DOMAIN, - ) - .map_err(ValidationError::Sigverify)?; + ) { + return Err(ValidationError::Sigverify); + } Ok(()) } @@ -500,13 +501,9 @@ fn extra_validation( #[cfg(test)] mod tests { - use alloy::{ - primitives::{B256, U256}, - rpc::types::beacon::BlsPublicKey, - }; - use blst::min_pk; + use alloy::primitives::{B256, U256}; use cb_common::{ - pbs::{error::ValidationError, ExecutionPayloadHeaderMessageElectra, EMPTY_TX_ROOT_HASH}, + pbs::{error::ValidationError, BlsSecretKey, EMPTY_TX_ROOT_HASH}, signature::sign_builder_message, types::Chain, utils::timestamp_of_slot_start_sec, @@ -573,33 +570,39 @@ mod tests { #[test] fn test_validate_signature() { - let secret_key = min_pk::SecretKey::from_bytes(&[ + let secret_key = BlsSecretKey::deserialize(&[ 0, 136, 227, 100, 165, 57, 106, 129, 181, 15, 235, 189, 200, 120, 70, 99, 251, 144, 137, 181, 230, 124, 189, 193, 115, 153, 26, 0, 197, 135, 103, 63, ]) .unwrap(); - let pubkey = BlsPublicKey::from_slice(&secret_key.sk_to_pk().to_bytes()); + let pubkey = secret_key.public_key(); + + let wrong_pubkey = BlsPublicKey::deserialize(&[ + 0, 136, 227, 100, 165, 57, 106, 129, 181, 15, 235, 189, 200, 120, 70, 99, 251, 144, + 137, 181, 230, 124, 189, 193, 115, 153, 26, 0, 197, 135, 103, 65, + ]) + .unwrap(); + + let wrong_signature = BlsSignature::deserialize(&[ + 0, 136, 227, 100, 165, 57, 106, 129, 181, 15, 235, 189, 200, 120, 70, 99, 251, 144, + 137, 181, 230, 124, 189, 193, 115, 153, 26, 0, 197, 135, 103, 65, + ]) + .unwrap(); - let message = ExecutionPayloadHeaderMessageElectra::default(); + let message = B256::random(); let signature = sign_builder_message(Chain::Holesky, &secret_key, &message); assert_eq!( - validate_signature( - Chain::Holesky, - BlsPublicKey::default(), - pubkey, - &message, - &BlsSignature::default() - ), - Err(ValidationError::PubkeyMismatch { expected: BlsPublicKey::default(), got: pubkey }) + validate_signature(Chain::Holesky, &wrong_pubkey, &pubkey, &message, &wrong_signature), + Err(ValidationError::PubkeyMismatch { expected: wrong_pubkey, got: pubkey.clone() }) ); assert!(matches!( - validate_signature(Chain::Holesky, pubkey, pubkey, &message, &BlsSignature::default()), - Err(ValidationError::Sigverify(_)) + validate_signature(Chain::Holesky, &pubkey, &pubkey, &message, &wrong_signature), + Err(ValidationError::Sigverify) )); - assert!(validate_signature(Chain::Holesky, pubkey, pubkey, &message, &signature).is_ok()); + assert!(validate_signature(Chain::Holesky, &pubkey, &pubkey, &message, &signature).is_ok()); } } diff --git a/crates/pbs/src/routes/get_header.rs b/crates/pbs/src/routes/get_header.rs index b6f55fa0..53aa194d 100644 --- a/crates/pbs/src/routes/get_header.rs +++ b/crates/pbs/src/routes/get_header.rs @@ -26,11 +26,11 @@ pub async fn handle_get_header>( ) -> Result { tracing::Span::current().record("slot", params.slot); tracing::Span::current().record("parent_hash", tracing::field::debug(params.parent_hash)); - tracing::Span::current().record("validator", tracing::field::debug(params.pubkey)); + tracing::Span::current().record("validator", tracing::field::debug(¶ms.pubkey)); let state = state.read().clone(); - state.publish_event(BuilderEvent::GetHeaderRequest(params)); + state.publish_event(BuilderEvent::GetHeaderRequest(params.clone())); let ua = get_user_agent(&req_headers); let ms_into_slot = ms_into_slot(params.slot, state.config.chain); diff --git a/crates/pbs/src/state.rs b/crates/pbs/src/state.rs index 3b892c63..3381af9d 100644 --- a/crates/pbs/src/state.rs +++ b/crates/pbs/src/state.rs @@ -1,9 +1,8 @@ use std::sync::Arc; -use alloy::rpc::types::beacon::BlsPublicKey; use cb_common::{ config::{PbsConfig, PbsModuleConfig}, - pbs::{BuilderEvent, RelayClient}, + pbs::{BlsPublicKey, BuilderEvent, RelayClient}, }; use parking_lot::RwLock; diff --git a/crates/signer/src/manager/dirk.rs b/crates/signer/src/manager/dirk.rs index 4c2d909f..c3d2d717 100644 --- a/crates/signer/src/manager/dirk.rs +++ b/crates/signer/src/manager/dirk.rs @@ -1,13 +1,14 @@ use std::{collections::HashMap, io::Write, path::PathBuf}; -use alloy::{hex, rpc::types::beacon::constants::BLS_SIGNATURE_BYTES_LEN}; +use alloy::{hex, primitives::B256}; use blsful::inner_types::{Field, G2Affine, G2Projective, Group, Scalar}; use cb_common::{ commit::request::{ConsensusProxyMap, ProxyDelegation, SignedProxyDelegation}, config::{DirkConfig, DirkHostConfig}, constants::COMMIT_BOOST_DOMAIN, + pbs::{BlsPublicKey, BlsSignature}, signature::compute_domain, - signer::{BlsPublicKey, BlsSignature, ProxyStore}, + signer::ProxyStore, types::{Chain, ModuleId}, }; use eyre::{bail, OptionExt}; @@ -57,10 +58,10 @@ struct DistributedAccount { } impl Account { - pub fn public_key(&self) -> BlsPublicKey { + pub fn public_key(&self) -> &BlsPublicKey { match self { - Account::Simple(account) => account.public_key, - Account::Distributed(account) => account.composite_public_key, + Account::Simple(account) => &account.public_key, + Account::Distributed(account) => &account.composite_public_key, } } } @@ -168,7 +169,7 @@ impl DirkManager { self.consensus_accounts .values() .map(|account| ConsensusProxyMap { - consensus: account.public_key(), + consensus: account.public_key().clone(), proxy_bls: self .proxy_accounts .values() @@ -176,7 +177,7 @@ impl DirkManager { if proxy.module == *module && proxy.consensus.public_key() == account.public_key() { - Some(proxy.inner.public_key()) + Some(proxy.inner.public_key().clone()) } else { None } @@ -192,7 +193,7 @@ impl DirkManager { pub async fn request_consensus_signature( &self, pubkey: &BlsPublicKey, - object_root: [u8; 32], + object_root: B256, ) -> Result { match self.consensus_accounts.get(pubkey) { Some(Account::Simple(account)) => { @@ -201,7 +202,7 @@ impl DirkManager { Some(Account::Distributed(account)) => { self.request_distributed_signature(account, object_root).await } - None => Err(SignerModuleError::UnknownConsensusSigner(pubkey.to_vec())), + None => Err(SignerModuleError::UnknownConsensusSigner(pubkey.serialize().to_vec())), } } @@ -209,7 +210,7 @@ impl DirkManager { pub async fn request_proxy_signature( &self, pubkey: &BlsPublicKey, - object_root: [u8; 32], + object_root: B256, ) -> Result { match self.proxy_accounts.get(pubkey) { Some(ProxyAccount { inner: Account::Simple(account), .. }) => { @@ -218,7 +219,7 @@ impl DirkManager { Some(ProxyAccount { inner: Account::Distributed(account), .. }) => { self.request_distributed_signature(account, object_root).await } - None => Err(SignerModuleError::UnknownProxySigner(pubkey.to_vec())), + None => Err(SignerModuleError::UnknownProxySigner(pubkey.serialize().to_vec())), } } @@ -226,7 +227,7 @@ impl DirkManager { async fn request_simple_signature( &self, account: &SimpleAccount, - object_root: [u8; 32], + object_root: B256, ) -> Result { let domain = compute_domain(self.chain, COMMIT_BOOST_DOMAIN); @@ -234,7 +235,7 @@ impl DirkManager { .sign(SignRequest { data: object_root.to_vec(), domain: domain.to_vec(), - id: Some(sign_request::Id::PublicKey(account.public_key.to_vec())), + id: Some(sign_request::Id::PublicKey(account.public_key.serialize().to_vec())), }) .await .map_err(|e| { @@ -247,7 +248,7 @@ impl DirkManager { )); } - BlsSignature::try_from(response.into_inner().signature.as_slice()).map_err(|_| { + BlsSignature::deserialize(response.into_inner().signature.as_slice()).map_err(|_| { SignerModuleError::DirkCommunicationError("Failed to parse signature".to_string()) }) } @@ -256,7 +257,7 @@ impl DirkManager { async fn request_distributed_signature( &self, account: &DistributedAccount, - object_root: [u8; 32], + object_root: B256, ) -> Result { let mut partials = Vec::with_capacity(account.participants.len()); let mut requests = Vec::with_capacity(account.participants.len()); @@ -291,14 +292,14 @@ impl DirkManager { continue; } - let signature = match BlsSignature::try_from(response.into_inner().signature.as_slice()) - { - Ok(sig) => sig, - Err(e) => { - warn!("Failed to parse signature from participant {participant_id}: {e}"); - continue; - } - }; + let signature = + match BlsSignature::deserialize(response.into_inner().signature.as_slice()) { + Ok(sig) => sig, + Err(e) => { + warn!("Failed to parse signature from participant {participant_id}: {e:?}"); + continue; + } + }; partials.push((signature, participant_id)); @@ -330,13 +331,19 @@ impl DirkManager { Some(Account::Distributed(account)) => { self.generate_distributed_proxy_key(account, module).await? } - None => return Err(SignerModuleError::UnknownConsensusSigner(consensus.to_vec())), + None => { + return Err(SignerModuleError::UnknownConsensusSigner( + consensus.serialize().to_vec(), + )) + } }; - let message = - ProxyDelegation { delegator: consensus, proxy: proxy_account.inner.public_key() }; + let message = ProxyDelegation { + delegator: consensus.clone(), + proxy: proxy_account.inner.public_key().clone(), + }; let delegation_signature = - self.request_consensus_signature(&consensus, message.tree_hash_root().0).await?; + self.request_consensus_signature(&consensus, message.tree_hash_root()).await?; let delegation = SignedProxyDelegation { message, signature: delegation_signature }; @@ -347,7 +354,7 @@ impl DirkManager { })?; } - self.proxy_accounts.insert(proxy_account.inner.public_key(), proxy_account.clone()); + self.proxy_accounts.insert(proxy_account.inner.public_key().clone(), proxy_account.clone()); Ok(delegation) } @@ -378,7 +385,7 @@ impl DirkManager { ))); } - let proxy_key = BlsPublicKey::try_from(response.into_inner().public_key.as_slice()) + let proxy_key = BlsPublicKey::deserialize(response.into_inner().public_key.as_slice()) .map_err(|_| { SignerModuleError::DirkCommunicationError("Failed to parse proxy key".to_string()) })?; @@ -436,7 +443,8 @@ impl DirkManager { continue; } - let Ok(proxy_key) = BlsPublicKey::try_from(response.into_inner().public_key.as_slice()) + let Ok(proxy_key) = + BlsPublicKey::deserialize(response.into_inner().public_key.as_slice()) else { warn!("Failed to parse proxy key with participant {id}"); continue; @@ -565,10 +573,10 @@ fn load_simple_accounts( continue; } - match BlsPublicKey::try_from(account.public_key.as_slice()) { + match BlsPublicKey::deserialize(account.public_key.as_slice()) { Ok(public_key) => { consensus_accounts.insert( - public_key, + public_key.clone(), Account::Simple(SimpleAccount { public_key, connection: channel.clone(), @@ -603,7 +611,8 @@ fn load_distributed_accounts( continue; } - let Ok(public_key) = BlsPublicKey::try_from(account.composite_public_key.as_slice()) else { + let Ok(public_key) = BlsPublicKey::deserialize(account.composite_public_key.as_slice()) + else { warn!("Failed to parse composite public key for account {}", account.name); continue; }; @@ -637,7 +646,7 @@ fn load_distributed_accounts( participants.insert(participant_id as u32, channel.clone()); consensus_accounts.insert( - public_key, + public_key.clone(), Account::Distributed(DistributedAccount { composite_public_key: public_key, participants, @@ -660,10 +669,7 @@ fn aggregate_partial_signatures(partials: &[(BlsSignature, u32)]) -> eyre::Resul // Deserialize partial signatures into G2 points let mut shares: HashMap = HashMap::new(); for (signature, id) in partials { - if signature.len() != BLS_SIGNATURE_BYTES_LEN { - bail!("Invalid signature length") - } - let affine = G2Affine::from_compressed(signature) + let affine = G2Affine::from_compressed(&signature.serialize()) .into_option() .ok_or_eyre("Failed to deserialize signature")?; shares.insert(*id, G2Projective::from(&affine)); @@ -693,7 +699,10 @@ fn aggregate_partial_signatures(partials: &[(BlsSignature, u32)]) -> eyre::Resul // Serialize the recovered point back into a BlsSignature let bytes = recovered.to_compressed(); - Ok(bytes.into()) + let sig = BlsSignature::deserialize(&bytes) + .map_err(|_| eyre::eyre!("Failed to deserialize aggregated signature"))?; + + Ok(sig) } /// Generate a random password of 64 hex-characters @@ -710,21 +719,22 @@ fn name_matches_proxy(name: &str) -> bool { name.rsplit_once("/").is_some_and(|(_, name)| uuid::Uuid::parse_str(name).is_ok()) } -mod test { +#[cfg(test)] +mod tests { + use super::*; #[test] fn test_signature_aggregation() { use alloy::hex; - use cb_common::signer::BlsSignature; use super::aggregate_partial_signatures; let partials = vec![ - (BlsSignature::from_slice(&hex::decode("aa16233b9e65b596caf070122d564ad7a021dad4fc2ed8508fccecfab010da80892fad7336e9fbada607c50e2d0d78e00c9961f26618334ec9f0e7ea225212f3c0c7d66f73ff1c2e555712a3e31f517b8329bd0ad9e15a9aeaa91521ba83502c").unwrap()), 1), - (BlsSignature::from_slice(&hex::decode("b27dd4c088e386edc4d07b6b23c72ba87a34e04cffd4975e8cb679aa4640cec1d34ace3e2bf33ac0dffca023c82422840012bb6c92eab36ca7908a9f9519fa18b1ed2bdbc624a98e01ca217c318a021495cc6cc9c8b982d0afed2cd83dc8fe65").unwrap()), 2), - (BlsSignature::from_slice(&hex::decode("aca4a71373df2f76369e8b242b0e2b1f41fc384feee3abe605ee8d6723f5fb11de1c9bd2408f4a09be981342352c523801e3beea73893a329204dd67fe84cb520220af33f7fa027b6bcc3b7c8e78647f2aa372145e4d3aec7682d2605040a64a").unwrap()), 3) + (BlsSignature::deserialize(&hex::decode("aa16233b9e65b596caf070122d564ad7a021dad4fc2ed8508fccecfab010da80892fad7336e9fbada607c50e2d0d78e00c9961f26618334ec9f0e7ea225212f3c0c7d66f73ff1c2e555712a3e31f517b8329bd0ad9e15a9aeaa91521ba83502c").unwrap()).unwrap(), 1), + (BlsSignature::deserialize(&hex::decode("b27dd4c088e386edc4d07b6b23c72ba87a34e04cffd4975e8cb679aa4640cec1d34ace3e2bf33ac0dffca023c82422840012bb6c92eab36ca7908a9f9519fa18b1ed2bdbc624a98e01ca217c318a021495cc6cc9c8b982d0afed2cd83dc8fe65").unwrap()).unwrap(), 2), + (BlsSignature::deserialize(&hex::decode("aca4a71373df2f76369e8b242b0e2b1f41fc384feee3abe605ee8d6723f5fb11de1c9bd2408f4a09be981342352c523801e3beea73893a329204dd67fe84cb520220af33f7fa027b6bcc3b7c8e78647f2aa372145e4d3aec7682d2605040a64a").unwrap()).unwrap(), 3) ]; - let expected = BlsSignature::from_slice(&hex::decode("0x8e343f074f91d19fd5118d9301768e30cecb21fb96a1ad9539cbdeae8907e2e12a88c91fe1d7e1f6995dcde18fb0272b1512cd68800e14ebd1c7f189e7221ba238a0f196226385737157f4b72d348c1886ce18d0a9609ba0cd5503e41546286f").unwrap()); + let expected = BlsSignature::deserialize(&hex::decode("0x8e343f074f91d19fd5118d9301768e30cecb21fb96a1ad9539cbdeae8907e2e12a88c91fe1d7e1f6995dcde18fb0272b1512cd68800e14ebd1c7f189e7221ba238a0f196226385737157f4b72d348c1886ce18d0a9609ba0cd5503e41546286f").unwrap()).unwrap(); // With all signers let signature = aggregate_partial_signatures(&partials).unwrap(); diff --git a/crates/signer/src/manager/local.rs b/crates/signer/src/manager/local.rs index 6d9e35fe..df6743df 100644 --- a/crates/signer/src/manager/local.rs +++ b/crates/signer/src/manager/local.rs @@ -1,14 +1,15 @@ use std::collections::HashMap; -use alloy::{primitives::Address, rpc::types::beacon::BlsSignature}; +use alloy::primitives::{Address, B256}; use cb_common::{ commit::request::{ - ConsensusProxyMap, ProxyDelegationBls, ProxyDelegationEcdsa, SignedProxyDelegationBls, - SignedProxyDelegationEcdsa, + ConsensusProxyMap, ProxyDelegationBls, ProxyDelegationEcdsa, ProxyId, + SignedProxyDelegationBls, SignedProxyDelegationEcdsa, }, + pbs::{BlsPublicKey, BlsSignature}, signer::{ - BlsProxySigner, BlsPublicKey, BlsSigner, ConsensusSigner, EcdsaProxySigner, EcdsaSignature, - EcdsaSigner, ProxySigners, ProxyStore, + BlsProxySigner, BlsSigner, ConsensusSigner, EcdsaProxySigner, EcdsaSignature, EcdsaSigner, + ProxySigners, ProxyStore, }, types::{Chain, ModuleId}, }; @@ -94,10 +95,10 @@ impl LocalSigningManager { let signer = BlsSigner::new_random(); let proxy_pubkey = signer.pubkey(); - let message = ProxyDelegationBls { delegator, proxy: proxy_pubkey }; - let signature = self.sign_consensus(&delegator, &message.tree_hash_root().0).await?; + let message = ProxyDelegationBls { delegator: delegator.clone(), proxy: proxy_pubkey }; + let signature = self.sign_consensus(&delegator, message.tree_hash_root()).await?; let delegation = SignedProxyDelegationBls { signature, message }; - let proxy_signer = BlsProxySigner { signer, delegation }; + let proxy_signer = BlsProxySigner { signer, delegation: delegation.clone() }; self.add_proxy_signer_bls(proxy_signer, module_id) .map_err(|err| SignerModuleError::Internal(err.to_string()))?; @@ -113,10 +114,10 @@ impl LocalSigningManager { let signer = EcdsaSigner::new_random(); let proxy_address = signer.address(); - let message = ProxyDelegationEcdsa { delegator, proxy: proxy_address }; - let signature = self.sign_consensus(&delegator, &message.tree_hash_root().0).await?; + let message = ProxyDelegationEcdsa { delegator: delegator.clone(), proxy: proxy_address }; + let signature = self.sign_consensus(&delegator, message.tree_hash_root()).await?; let delegation = SignedProxyDelegationEcdsa { signature, message }; - let proxy_signer = EcdsaProxySigner { signer, delegation }; + let proxy_signer = EcdsaProxySigner { signer, delegation: delegation.clone() }; self.add_proxy_signer_ecdsa(proxy_signer, module_id) .map_err(|err| SignerModuleError::Internal(err.to_string()))?; @@ -129,13 +130,13 @@ impl LocalSigningManager { pub async fn sign_consensus( &self, pubkey: &BlsPublicKey, - object_root: &[u8; 32], + object_root: B256, ) -> Result { let signer = self .consensus_signers .get(pubkey) - .ok_or(SignerModuleError::UnknownConsensusSigner(pubkey.to_vec()))?; - let signature = signer.sign(self.chain, *object_root).await; + .ok_or(SignerModuleError::UnknownConsensusSigner(pubkey.to_bytes()))?; + let signature = signer.sign(self.chain, object_root).await; Ok(signature) } @@ -143,28 +144,28 @@ impl LocalSigningManager { pub async fn sign_proxy_bls( &self, pubkey: &BlsPublicKey, - object_root: &[u8; 32], + object_root: B256, ) -> Result { let bls_proxy = self .proxy_signers .bls_signers .get(pubkey) - .ok_or(SignerModuleError::UnknownProxySigner(pubkey.to_vec()))?; - let signature = bls_proxy.sign(self.chain, *object_root).await; + .ok_or(SignerModuleError::UnknownProxySigner(pubkey.serialize().to_vec()))?; + let signature = bls_proxy.sign(self.chain, object_root).await; Ok(signature) } pub async fn sign_proxy_ecdsa( &self, address: &Address, - object_root: &[u8; 32], + object_root: B256, ) -> Result { let ecdsa_proxy = self .proxy_signers .ecdsa_signers .get(address) .ok_or(SignerModuleError::UnknownProxySigner(address.to_vec()))?; - let signature = ecdsa_proxy.sign(self.chain, *object_root).await?; + let signature = ecdsa_proxy.sign(self.chain, object_root).await?; Ok(signature) } @@ -205,22 +206,22 @@ impl LocalSigningManager { pub fn get_delegation_bls( &self, pubkey: &BlsPublicKey, - ) -> Result { + ) -> Result<&SignedProxyDelegationBls, SignerModuleError> { self.proxy_signers .bls_signers .get(pubkey) - .map(|x| x.delegation) - .ok_or(SignerModuleError::UnknownProxySigner(pubkey.to_vec())) + .map(|x| &x.delegation) + .ok_or(SignerModuleError::UnknownProxySigner(pubkey.serialize().to_vec())) } pub fn get_delegation_ecdsa( &self, address: &Address, - ) -> Result { + ) -> Result<&SignedProxyDelegationEcdsa, SignerModuleError> { self.proxy_signers .ecdsa_signers .get(address) - .map(|x| x.delegation) + .map(|x| &x.delegation) .ok_or(SignerModuleError::UnknownProxySigner(address.to_vec())) } @@ -235,21 +236,21 @@ impl LocalSigningManager { let mut keys: Vec<_> = consensus.into_iter().map(ConsensusProxyMap::new).collect(); for bls in proxy_bls { - let delegator = self.get_delegation_bls(&bls)?.message.delegator; + let delegator = &self.get_delegation_bls(&bls)?.message.delegator; let entry = keys .iter_mut() - .find(|x| x.consensus == delegator) - .ok_or(SignerModuleError::UnknownConsensusSigner(delegator.0.to_vec()))?; + .find(|x| &x.consensus == delegator) + .ok_or(SignerModuleError::UnknownConsensusSigner(delegator.serialize().to_vec()))?; entry.proxy_bls.push(bls); } for ecdsa in proxy_ecdsa { - let delegator = self.get_delegation_ecdsa(&ecdsa)?.message.delegator; + let delegator = &self.get_delegation_ecdsa(&ecdsa)?.message.delegator; let entry = keys .iter_mut() - .find(|x| x.consensus == delegator) - .ok_or(SignerModuleError::UnknownConsensusSigner(delegator.0.to_vec()))?; + .find(|x| &x.consensus == delegator) + .ok_or(SignerModuleError::UnknownConsensusSigner(delegator.serialize().to_vec()))?; entry.proxy_ecdsa.push(ecdsa); } @@ -306,7 +307,7 @@ mod tests { let validation_result = signed_delegation.validate(CHAIN); assert!( - validation_result.is_ok(), + validation_result, "Proxy delegation signature must be valid for consensus key." ); @@ -326,12 +327,13 @@ mod tests { .await .unwrap(); - let m = &mut signed_delegation.signature.0[0]; - (*m, _) = m.overflowing_add(1); + let mut m = signed_delegation.signature.serialize(); + m[0] = m[0].overflowing_add(1).0; + signed_delegation.signature = BlsSignature::deserialize(&m).unwrap(); let validation_result = signed_delegation.validate(CHAIN); - assert!(validation_result.is_err(), "Tampered proxy key must be invalid."); + assert!(!validation_result, "Tampered proxy key must be invalid."); } #[tokio::test] @@ -347,20 +349,17 @@ mod tests { let data_root = B256::random(); let sig = signing_manager - .sign_proxy_bls(&proxy_pk.try_into().unwrap(), &data_root) + .sign_proxy_bls(&proxy_pk.clone().try_into().unwrap(), data_root) .await .unwrap(); // Verify signature let domain = compute_domain(CHAIN, COMMIT_BOOST_DOMAIN); - let signing_root = compute_signing_root(data_root.tree_hash_root().0, domain); + let signing_root = compute_signing_root(data_root.tree_hash_root(), domain); - let validation_result = verify_bls_signature(&proxy_pk, &signing_root, &sig); + let validation_result = verify_bls_signature(&proxy_pk, signing_root, &sig); - assert!( - validation_result.is_ok(), - "Proxy keypair must produce valid signatures of messages." - ) + assert!(validation_result, "Proxy keypair must produce valid signatures of messages.") } } @@ -384,7 +383,7 @@ mod tests { let validation_result = signed_delegation.validate(CHAIN); assert!( - validation_result.is_ok(), + validation_result, "Proxy delegation signature must be valid for consensus key." ); @@ -404,12 +403,13 @@ mod tests { .await .unwrap(); - let m = &mut signed_delegation.signature.0[0]; - (*m, _) = m.overflowing_add(1); + let mut m = signed_delegation.signature.serialize(); + m[0] = m[0].overflowing_add(1).0; + signed_delegation.signature = BlsSignature::deserialize(&m).unwrap(); let validation_result = signed_delegation.validate(CHAIN); - assert!(validation_result.is_err(), "Tampered proxy key must be invalid."); + assert!(!validation_result, "Tampered proxy key must be invalid."); } #[tokio::test] @@ -425,13 +425,13 @@ mod tests { let data_root = B256::random(); let sig = signing_manager - .sign_proxy_ecdsa(&proxy_pk.try_into().unwrap(), &data_root) + .sign_proxy_ecdsa(&proxy_pk.try_into().unwrap(), data_root) .await .unwrap(); // Verify signature let domain = compute_domain(CHAIN, COMMIT_BOOST_DOMAIN); - let signing_root = compute_signing_root(data_root.tree_hash_root().0, domain); + let signing_root = compute_signing_root(data_root.tree_hash_root(), domain); let validation_result = verify_ecdsa_signature(&proxy_pk, &signing_root, &sig); diff --git a/crates/signer/src/service.rs b/crates/signer/src/service.rs index 1a41a008..ab223829 100644 --- a/crates/signer/src/service.rs +++ b/crates/signer/src/service.rs @@ -274,29 +274,29 @@ async fn handle_request_signature( let res = match &*manager { SigningManager::Local(local_manager) => match request { SignRequest::Consensus(SignConsensusRequest { object_root, pubkey }) => local_manager - .sign_consensus(&pubkey, &object_root) + .sign_consensus(&pubkey, object_root) .await .map(|sig| Json(sig).into_response()), SignRequest::ProxyBls(SignProxyRequest { object_root, proxy: bls_key }) => { local_manager - .sign_proxy_bls(&bls_key, &object_root) + .sign_proxy_bls(&bls_key, object_root) .await .map(|sig| Json(sig).into_response()) } SignRequest::ProxyEcdsa(SignProxyRequest { object_root, proxy: ecdsa_key }) => { local_manager - .sign_proxy_ecdsa(&ecdsa_key, &object_root) + .sign_proxy_ecdsa(&ecdsa_key, object_root) .await .map(|sig| Json(sig).into_response()) } }, SigningManager::Dirk(dirk_manager) => match request { SignRequest::Consensus(SignConsensusRequest { object_root, pubkey }) => dirk_manager - .request_consensus_signature(&pubkey, *object_root) + .request_consensus_signature(&pubkey, object_root) .await .map(|sig| Json(sig).into_response()), SignRequest::ProxyBls(SignProxyRequest { object_root, proxy: bls_key }) => dirk_manager - .request_proxy_signature(&bls_key, *object_root) + .request_proxy_signature(&bls_key, object_root) .await .map(|sig| Json(sig).into_response()), SignRequest::ProxyEcdsa(_) => { diff --git a/examples/da_commit/src/main.rs b/examples/da_commit/src/main.rs index 71b61c53..7db8c255 100644 --- a/examples/da_commit/src/main.rs +++ b/examples/da_commit/src/main.rs @@ -49,16 +49,17 @@ impl DaCommitService { let pubkeys = self.config.signer_client.get_pubkeys().await?.keys; info!(pubkeys = %serde_json::to_string_pretty(&pubkeys).unwrap(), "Received pubkeys"); - let pubkey = pubkeys.first().ok_or_eyre("no key available")?.consensus; + let pubkey = pubkeys.first().ok_or_eyre("no key available")?.consensus.clone(); info!("Registered validator {pubkey}"); - let proxy_delegation_bls = self.config.signer_client.generate_proxy_key_bls(pubkey).await?; + let proxy_delegation_bls = + self.config.signer_client.generate_proxy_key_bls(pubkey.clone()).await?; info!("Obtained a BLS proxy delegation:\n{proxy_delegation_bls}"); let proxy_bls = proxy_delegation_bls.message.proxy; let proxy_ecdsa = if self.config.extra.use_ecdsa_keys { let proxy_delegation_ecdsa = - self.config.signer_client.generate_proxy_key_ecdsa(pubkey).await?; + self.config.signer_client.generate_proxy_key_ecdsa(pubkey.clone()).await?; info!("Obtained an ECDSA proxy delegation:\n{proxy_delegation_ecdsa}"); Some(proxy_delegation_ecdsa.message.proxy) } else { @@ -68,7 +69,7 @@ impl DaCommitService { let mut data = 0; loop { - self.send_request(data, pubkey, proxy_bls, proxy_ecdsa).await?; + self.send_request(data, pubkey.clone(), proxy_bls.clone(), proxy_ecdsa.clone()).await?; sleep(Duration::from_secs(self.config.extra.sleep_secs)).await; data += 1; } diff --git a/tests/src/mock_relay.rs b/tests/src/mock_relay.rs index a91a70c6..ae46464e 100644 --- a/tests/src/mock_relay.rs +++ b/tests/src/mock_relay.rs @@ -16,14 +16,14 @@ use axum::{ }; use cb_common::{ pbs::{ - ExecutionPayloadHeaderMessageElectra, GetHeaderParams, GetHeaderResponse, - SignedExecutionPayloadHeader, SubmitBlindedBlockResponse, BUILDER_API_PATH, - GET_HEADER_PATH, GET_STATUS_PATH, REGISTER_VALIDATOR_PATH, SUBMIT_BLOCK_PATH, + BlsSecretKey, ExecutionPayloadHeaderMessageElectra, ExecutionRequests, GetHeaderParams, + GetHeaderResponse, SignedExecutionPayloadHeader, SubmitBlindedBlockResponse, + BUILDER_API_PATH, GET_HEADER_PATH, GET_STATUS_PATH, REGISTER_VALIDATOR_PATH, + SUBMIT_BLOCK_PATH, }, signature::sign_builder_root, - signer::BlsSecretKey, types::Chain, - utils::{blst_pubkey_to_alloy, timestamp_of_slot_start_sec}, + utils::timestamp_of_slot_start_sec, }; use cb_pbs::MAX_SIZE_SUBMIT_BLOCK_RESPONSE; use tokio::net::TcpListener; @@ -108,17 +108,23 @@ async fn handle_get_header( ) -> Response { state.received_get_header.fetch_add(1, Ordering::Relaxed); - let mut response: SignedExecutionPayloadHeader = - SignedExecutionPayloadHeader::default(); - - response.message.header.parent_hash = parent_hash; - response.message.header.block_hash.0[0] = 1; - response.message.value = U256::from(10); - response.message.pubkey = blst_pubkey_to_alloy(&state.signer.sk_to_pk()); - response.message.header.timestamp = timestamp_of_slot_start_sec(0, state.chain); - - let object_root = response.message.tree_hash_root().0; - response.signature = sign_builder_root(state.chain, &state.signer, object_root); + let mut message = ExecutionPayloadHeaderMessageElectra { + header: Default::default(), + blob_kzg_commitments: Default::default(), + execution_requests: ExecutionRequests::default(), + value: Default::default(), + pubkey: state.signer.public_key(), + }; + + message.header.parent_hash = parent_hash; + message.header.block_hash.0[0] = 1; + message.value = U256::from(10); + message.pubkey = state.signer.public_key(); + message.header.timestamp = timestamp_of_slot_start_sec(0, state.chain); + + let object_root = message.tree_hash_root(); + let signature = sign_builder_root(state.chain, &state.signer, object_root); + let response = SignedExecutionPayloadHeader { message, signature }; let response = GetHeaderResponse::Electra(response); (StatusCode::OK, Json(response)).into_response() diff --git a/tests/src/mock_validator.rs b/tests/src/mock_validator.rs index 7d31f770..bb50c0ff 100644 --- a/tests/src/mock_validator.rs +++ b/tests/src/mock_validator.rs @@ -1,8 +1,5 @@ -use alloy::{ - primitives::B256, - rpc::types::beacon::{relay::ValidatorRegistration, BlsPublicKey}, -}; -use cb_common::pbs::{RelayClient, SignedBlindedBeaconBlock}; +use alloy::{hex, primitives::B256, rpc::types::beacon::relay::ValidatorRegistration}; +use cb_common::pbs::{BlsPublicKey, RelayClient, SignedBlindedBeaconBlock}; use reqwest::Response; use crate::utils::generate_mock_relay; @@ -13,11 +10,14 @@ pub struct MockValidator { impl MockValidator { pub fn new(port: u16) -> eyre::Result { - Ok(Self { comm_boost: generate_mock_relay(port, BlsPublicKey::default())? }) + let pubkey = BlsPublicKey::deserialize(&hex!("0xac6e77dfe25ecd6110b8e780608cce0dab71fdd5ebea22a16c0205200f2f8e2e3ad3b71d3499c54ad14d6c21b41a37ae")).unwrap(); + Ok(Self { comm_boost: generate_mock_relay(port, pubkey)? }) } pub async fn do_get_header(&self, pubkey: Option) -> eyre::Result { - let url = self.comm_boost.get_header_url(0, B256::ZERO, pubkey.unwrap_or_default())?; + let default_pubkey = BlsPublicKey::deserialize(&hex!("0xac6e77dfe25ecd6110b8e780608cce0dab71fdd5ebea22a16c0205200f2f8e2e3ad3b71d3499c54ad14d6c21b41a37ae")).unwrap(); + let url = + self.comm_boost.get_header_url(0, &B256::ZERO, &pubkey.unwrap_or(default_pubkey))?; Ok(self.comm_boost.client.get(url).send().await?) } @@ -45,12 +45,14 @@ impl MockValidator { ) -> eyre::Result { let url = self.comm_boost.submit_block_url().unwrap(); - Ok(self - .comm_boost - .client - .post(url) - .json(&signed_blinded_block.unwrap_or_default()) - .send() - .await?) + let signed_blinded_block = + signed_blinded_block.unwrap_or_else(|| load_test_signed_blinded_block()); + + Ok(self.comm_boost.client.post(url).json(&signed_blinded_block).send().await?) } } + +pub fn load_test_signed_blinded_block() -> SignedBlindedBeaconBlock { + let data_json = include_str!("signed-blinded-beacon-block-electra-2.json"); + serde_json::from_str(&data_json).unwrap() +} diff --git a/tests/src/signed-blinded-beacon-block-electra-2.json b/tests/src/signed-blinded-beacon-block-electra-2.json new file mode 100644 index 00000000..81c8743b --- /dev/null +++ b/tests/src/signed-blinded-beacon-block-electra-2.json @@ -0,0 +1,223 @@ +{ + "message": { + "body": { + "attestations": [ + { + "aggregation_bits": "0x01", + "committee_bits": "0x0101010101010101", + "data": { + "beacon_block_root": "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20", + "index": "1", + "slot": "12345", + "source": { + "epoch": "1", + "root": "0x0200000000000000000000000000000000000000000000000000000000000000" + }, + "target": { + "epoch": "2", + "root": "0x0200000000000000000000000000000000000000000000000000000000000000" + } + }, + "signature": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + } + ], + "attester_slashings": [ + { + "attestation_1": { + "attesting_indices": [ + "1", + "2", + "3" + ], + "data": { + "beacon_block_root": "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20", + "index": "1", + "slot": "789", + "source": { + "epoch": "1", + "root": "0x0100000000000000000000000000000000000000000000000000000000000000" + }, + "target": { + "epoch": "2", + "root": "0x0100000000000000000000000000000000000000000000000000000000000000" + } + }, + "signature": "0x8c3095fd9d3a18e43ceeb7648281e16b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + }, + "attestation_2": { + "attesting_indices": [ + "1", + "2", + "3" + ], + "data": { + "beacon_block_root": "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20", + "index": "1", + "slot": "789", + "source": { + "epoch": "1", + "root": "0x0200000000000000000000000000000000000000000000000000000000000000" + }, + "target": { + "epoch": "2", + "root": "0x0200000000000000000000000000000000000000000000000000000000000000" + } + }, + "signature": "0x8c3095fd9d3a18e43ceeb7648281e16b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + } + } + ], + "blob_kzg_commitments": [ + "0x010203000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ], + "bls_to_execution_changes": [ + { + "message": { + "from_bls_pubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "to_execution_address": "0x0000000000000000000000000000000000000000", + "validator_index": "1" + }, + "signature": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + } + ], + "deposits": [ + { + "data": { + "amount": "1", + "pubkey": "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2000000000000000000000000000000000", + "signature": "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "withdrawal_credentials": "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20" + }, + "proof": [ + "0x0101010101010101010101010101010101010101010101010101010101010101", + "0x0202020202020202020202020202020202020202020202020202020202020202", + "0x0303030303030303030303030303030303030303030303030303030303030303", + "0x0404040404040404040404040404040404040404040404040404040404040404", + "0x0505050505050505050505050505050505050505050505050505050505050505", + "0x0606060606060606060606060606060606060606060606060606060606060606", + "0x0707070707070707070707070707070707070707070707070707070707070707", + "0x0808080808080808080808080808080808080808080808080808080808080808", + "0x0909090909090909090909090909090909090909090909090909090909090909", + "0x0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a", + "0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", + "0x0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c", + "0x0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d", + "0x0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e", + "0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f", + "0x1010101010101010101010101010101010101010101010101010101010101010", + "0x1111111111111111111111111111111111111111111111111111111111111111", + "0x1212121212121212121212121212121212121212121212121212121212121212", + "0x1313131313131313131313131313131313131313131313131313131313131313", + "0x1414141414141414141414141414141414141414141414141414141414141414", + "0x1515151515151515151515151515151515151515151515151515151515151515", + "0x1616161616161616161616161616161616161616161616161616161616161616", + "0x1717171717171717171717171717171717171717171717171717171717171717", + "0x1818181818181818181818181818181818181818181818181818181818181818", + "0x1919191919191919191919191919191919191919191919191919191919191919", + "0x1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a", + "0x1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b", + "0x1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c", + "0x1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d", + "0x1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e", + "0x1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f", + "0x2020202020202020202020202020202020202020202020202020202020202020", + "0x2121212121212121212121212121212121212121212121212121212121212121" + ] + } + ], + "eth1_data": { + "block_hash": "0xd75a680056c50b4e339eda2f91ccd33bd75a680056c50b4e339eda2f91ccd33b", + "deposit_count": "216773", + "deposit_root": "0x0cacd599c9cdcee8398b40ef045baf2c00000000000000000000000000000000" + }, + "execution_payload_header": { + "base_fee_per_gas": "7", + "blob_gas_used": "0", + "block_hash": "0xb65b77e52407ff25000000000000000000000000000000000000000000000000", + "block_number": "220275", + "excess_blob_gas": "100", + "extra_data": "0x74657374", + "fee_recipient": "0xf97e180c050e5ab0000000000000000000000000", + "gas_limit": "30000000", + "gas_used": "84000", + "logs_bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "parent_hash": "0x98b62322edaa4d91000000000000000000000000000000000000000000000000", + "prev_randao": "0x83612b3de54001f7000000000000000000000000000000000000000000000000", + "receipts_root": "0x04deb4be6955e1a3000000000000000000000000000000000000000000000000", + "state_root": "0x3b6b594d5cbe7ff4000000000000000000000000000000000000000000000000", + "timestamp": "1732296378", + "transactions_root": "0xb1fcd304d8ba402b000000000000000000000000000000000000000000000000", + "withdrawals_root": "0x792930bbd5baac43000000000000000000000000000000000000000000000000" + }, + "execution_requests": { + "consolidations": [ + { + "source_address": "0x0100000000000000000000000000000000000000", + "source_pubkey": "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2000000000000000000000000000000000", + "target_pubkey": "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2000000000000000000000000000000000" + } + ], + "deposits": [ + { + "amount": "32000000000", + "index": "0", + "pubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "signature": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "withdrawal_credentials": "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20" + } + ], + "withdrawals": [ + { + "amount": "0", + "source_address": "0x0100000000000000000000000000000000000000", + "validator_pubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + } + ] + }, + "graffiti": "0x6c69676874686f75736500000000000000000000000000000000000000000000", + "proposer_slashings": [ + { + "signed_header_1": { + "message": { + "body_root": "0x0000000000000000000000000000000000000000000000000000000000000000", + "parent_root": "0x0000000000000000000000000000000000000000000000000000000000000000", + "proposer_index": "456", + "slot": "123", + "state_root": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "signature": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + }, + "signed_header_2": { + "message": { + "body_root": "0x0000000000000000000000000000000000000000000000000000000000000000", + "parent_root": "0x0000000000000000000000000000000000000000000000000000000000000000", + "proposer_index": "456", + "slot": "123", + "state_root": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "signature": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + } + } + ], + "randao_reveal": "0xa7a74e03d8ef909abc75b9452d167e150000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "sync_aggregate": { + "sync_committee_bits": "0xff98b62322edaa4d9198b62322edaa4d9198b62322edaa4d91ff98b62322edaa4d9198b62322edaa4d9198b62322edaa4d912322edaa4d9198b62322edaa4d91", + "sync_committee_signature": "0x8c3095fd9d3a18e43ceeb7648281e16b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + }, + "voluntary_exits": [ + { + "message": { + "epoch": "123", + "validator_index": "0" + }, + "signature": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + } + ] + }, + "parent_root": "0x9a8eef2096477e645150fee1a2ce13190382179a0ea843f31173715a1a14e074", + "proposer_index": "4295", + "slot": "252288", + "state_root": "0x4c033e0b4a34c0eb8e0caba126fae3ed303a83254fe39f8daaa673125f4042cc" + }, + "signature": "0x8c3095fd9d3a18e43ceeb7648281e16b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" +} \ No newline at end of file diff --git a/tests/src/utils.rs b/tests/src/utils.rs index d5409107..382d26f5 100644 --- a/tests/src/utils.rs +++ b/tests/src/utils.rs @@ -4,13 +4,13 @@ use std::{ sync::{Arc, Once}, }; -use alloy::{primitives::U256, rpc::types::beacon::BlsPublicKey}; +use alloy::primitives::U256; use cb_common::{ config::{ PbsConfig, PbsModuleConfig, RelayConfig, SignerConfig, SignerType, StartSignerConfig, SIGNER_IMAGE_DEFAULT, }, - pbs::{RelayClient, RelayEntry}, + pbs::{BlsPublicKey, RelayClient, RelayEntry}, signer::{ SignerLoader, DEFAULT_JWT_AUTH_FAIL_LIMIT, DEFAULT_JWT_AUTH_FAIL_TIMEOUT_SECONDS, DEFAULT_SIGNER_PORT, diff --git a/tests/tests/pbs_get_header.rs b/tests/tests/pbs_get_header.rs index 02cceb0a..eaae5367 100644 --- a/tests/tests/pbs_get_header.rs +++ b/tests/tests/pbs_get_header.rs @@ -2,11 +2,8 @@ use std::{sync::Arc, time::Duration}; use alloy::primitives::{B256, U256}; use cb_common::{ - pbs::GetHeaderResponse, - signature::sign_builder_root, - signer::{random_secret, BlsPublicKey}, - types::Chain, - utils::{blst_pubkey_to_alloy, timestamp_of_slot_start_sec}, + pbs::GetHeaderResponse, signature::sign_builder_root, signer::random_secret, types::Chain, + utils::timestamp_of_slot_start_sec, }; use cb_pbs::{DefaultBuilderApi, PbsService, PbsState}; use cb_tests::{ @@ -23,7 +20,7 @@ use tree_hash::TreeHash; async fn test_get_header() -> Result<()> { setup_test_env(); let signer = random_secret(); - let pubkey: BlsPublicKey = blst_pubkey_to_alloy(&signer.sk_to_pk()); + let pubkey = signer.public_key(); let chain = Chain::Holesky; let pbs_port = 3200; @@ -54,11 +51,11 @@ async fn test_get_header() -> Result<()> { assert_eq!(res.message.header.block_hash.0[0], 1); assert_eq!(res.message.header.parent_hash, B256::ZERO); assert_eq!(res.message.value, U256::from(10)); - assert_eq!(res.message.pubkey, blst_pubkey_to_alloy(&mock_state.signer.sk_to_pk())); + assert_eq!(res.message.pubkey, mock_state.signer.public_key()); assert_eq!(res.message.header.timestamp, timestamp_of_slot_start_sec(0, chain)); assert_eq!( res.signature, - sign_builder_root(chain, &mock_state.signer, res.message.tree_hash_root().0) + sign_builder_root(chain, &mock_state.signer, res.message.tree_hash_root()) ); Ok(()) } @@ -67,7 +64,7 @@ async fn test_get_header() -> Result<()> { async fn test_get_header_returns_204_if_relay_down() -> Result<()> { setup_test_env(); let signer = random_secret(); - let pubkey: BlsPublicKey = blst_pubkey_to_alloy(&signer.sk_to_pk()).into(); + let pubkey = signer.public_key(); let chain = Chain::Holesky; let pbs_port = 3300; @@ -101,7 +98,7 @@ async fn test_get_header_returns_204_if_relay_down() -> Result<()> { async fn test_get_header_returns_400_if_request_is_invalid() -> Result<()> { setup_test_env(); let signer = random_secret(); - let pubkey: BlsPublicKey = blst_pubkey_to_alloy(&signer.sk_to_pk()).into(); + let pubkey = signer.public_key(); let chain = Chain::Holesky; let pbs_port = 3400; @@ -109,7 +106,7 @@ async fn test_get_header_returns_400_if_request_is_invalid() -> Result<()> { // Run a mock relay let mock_state = Arc::new(MockRelayState::new(chain, signer)); - let mock_relay = generate_mock_relay(relay_port, pubkey)?; + let mock_relay = generate_mock_relay(relay_port, pubkey.clone())?; tokio::spawn(start_mock_relay_service(mock_state.clone(), relay_port)); // Run the PBS service @@ -121,7 +118,7 @@ async fn test_get_header_returns_400_if_request_is_invalid() -> Result<()> { tokio::time::sleep(Duration::from_millis(100)).await; // Create an invalid URL by truncating the pubkey - let mut bad_url = mock_relay.get_header_url(0, B256::ZERO, pubkey).unwrap(); + let mut bad_url = mock_relay.get_header_url(0, &B256::ZERO, &pubkey).unwrap(); bad_url.set_path(&bad_url.path().replace(&pubkey.to_string(), &pubkey.to_string()[..10])); let mock_validator = MockValidator::new(pbs_port)?; @@ -131,7 +128,7 @@ async fn test_get_header_returns_400_if_request_is_invalid() -> Result<()> { assert_eq!(res.status(), StatusCode::BAD_REQUEST); // Attempt again by truncating the parent hash - let mut bad_url = mock_relay.get_header_url(0, B256::ZERO, pubkey).unwrap(); + let mut bad_url = mock_relay.get_header_url(0, &B256::ZERO, &pubkey).unwrap(); bad_url .set_path(&bad_url.path().replace(&B256::ZERO.to_string(), &B256::ZERO.to_string()[..10])); let res = mock_validator.comm_boost.client.get(bad_url).send().await?; diff --git a/tests/tests/pbs_get_status.rs b/tests/tests/pbs_get_status.rs index 0694b97a..73a81e51 100644 --- a/tests/tests/pbs_get_status.rs +++ b/tests/tests/pbs_get_status.rs @@ -1,10 +1,6 @@ use std::{sync::Arc, time::Duration}; -use cb_common::{ - signer::{random_secret, BlsPublicKey}, - types::Chain, - utils::blst_pubkey_to_alloy, -}; +use cb_common::{signer::random_secret, types::Chain}; use cb_pbs::{DefaultBuilderApi, PbsService, PbsState}; use cb_tests::{ mock_relay::{start_mock_relay_service, MockRelayState}, @@ -19,7 +15,7 @@ use tracing::info; async fn test_get_status() -> Result<()> { setup_test_env(); let signer = random_secret(); - let pubkey: BlsPublicKey = blst_pubkey_to_alloy(&signer.sk_to_pk()).into(); + let pubkey = signer.public_key(); let chain = Chain::Holesky; let pbs_port = 3500; @@ -27,7 +23,7 @@ async fn test_get_status() -> Result<()> { let relay_1_port = pbs_port + 2; let relays = vec![ - generate_mock_relay(relay_0_port, pubkey)?, + generate_mock_relay(relay_0_port, pubkey.clone())?, generate_mock_relay(relay_1_port, pubkey)?, ]; let mock_state = Arc::new(MockRelayState::new(chain, signer)); @@ -55,7 +51,7 @@ async fn test_get_status() -> Result<()> { async fn test_get_status_returns_502_if_relay_down() -> Result<()> { setup_test_env(); let signer = random_secret(); - let pubkey: BlsPublicKey = blst_pubkey_to_alloy(&signer.sk_to_pk()).into(); + let pubkey = signer.public_key(); let chain = Chain::Holesky; let pbs_port = 3600; diff --git a/tests/tests/pbs_mux.rs b/tests/tests/pbs_mux.rs index a8f3ed1c..5f513dd4 100644 --- a/tests/tests/pbs_mux.rs +++ b/tests/tests/pbs_mux.rs @@ -1,11 +1,6 @@ use std::{collections::HashMap, sync::Arc, time::Duration}; -use cb_common::{ - config::RuntimeMuxConfig, - signer::{random_secret, BlsPublicKey}, - types::Chain, - utils::blst_pubkey_to_alloy, -}; +use cb_common::{config::RuntimeMuxConfig, signer::random_secret, types::Chain}; use cb_pbs::{DefaultBuilderApi, PbsService, PbsState}; use cb_tests::{ mock_relay::{start_mock_relay_service, MockRelayState}, @@ -20,14 +15,14 @@ use tracing::info; async fn test_mux() -> Result<()> { setup_test_env(); let signer = random_secret(); - let pubkey: BlsPublicKey = blst_pubkey_to_alloy(&signer.sk_to_pk()).into(); + let pubkey = signer.public_key(); let chain = Chain::Holesky; let pbs_port = 3700; - let mux_relay_1 = generate_mock_relay(pbs_port + 1, pubkey)?; - let mux_relay_2 = generate_mock_relay(pbs_port + 2, pubkey)?; - let default_relay = generate_mock_relay(pbs_port + 3, pubkey)?; + let mux_relay_1 = generate_mock_relay(pbs_port + 1, pubkey.clone())?; + let mux_relay_2 = generate_mock_relay(pbs_port + 2, pubkey.clone())?; + let default_relay = generate_mock_relay(pbs_port + 3, pubkey.clone())?; // Run 3 mock relays let mock_state = Arc::new(MockRelayState::new(chain, signer)); @@ -48,8 +43,8 @@ async fn test_mux() -> Result<()> { }; // Bind mux to a specific validator key - let validator_pubkey = blst_pubkey_to_alloy(&random_secret().sk_to_pk()); - config.muxes = Some(HashMap::from([(validator_pubkey, mux)])); + let validator_pubkey = random_secret().public_key(); + config.muxes = Some(HashMap::from([(validator_pubkey.clone(), mux)])); // Run PBS service let state = PbsState::new(config); diff --git a/tests/tests/pbs_post_blinded_blocks.rs b/tests/tests/pbs_post_blinded_blocks.rs index 3ab378a4..b80ce227 100644 --- a/tests/tests/pbs_post_blinded_blocks.rs +++ b/tests/tests/pbs_post_blinded_blocks.rs @@ -1,15 +1,10 @@ use std::{sync::Arc, time::Duration}; -use cb_common::{ - pbs::{SignedBlindedBeaconBlock, SubmitBlindedBlockResponse}, - signer::{random_secret, BlsPublicKey}, - types::Chain, - utils::blst_pubkey_to_alloy, -}; +use cb_common::{pbs::SubmitBlindedBlockResponse, signer::random_secret, types::Chain}; use cb_pbs::{DefaultBuilderApi, PbsService, PbsState}; use cb_tests::{ mock_relay::{start_mock_relay_service, MockRelayState}, - mock_validator::MockValidator, + mock_validator::{load_test_signed_blinded_block, MockValidator}, utils::{generate_mock_relay, get_pbs_static_config, setup_test_env, to_pbs_config}, }; use eyre::Result; @@ -20,7 +15,7 @@ use tracing::info; async fn test_submit_block() -> Result<()> { setup_test_env(); let signer = random_secret(); - let pubkey: BlsPublicKey = blst_pubkey_to_alloy(&signer.sk_to_pk()).into(); + let pubkey = signer.public_key(); let chain = Chain::Holesky; let pbs_port = 3800; @@ -39,14 +34,16 @@ async fn test_submit_block() -> Result<()> { tokio::time::sleep(Duration::from_millis(100)).await; let mock_validator = MockValidator::new(pbs_port)?; + + let signed_blinded_block = load_test_signed_blinded_block(); info!("Sending submit block"); - let res = mock_validator.do_submit_block(Some(SignedBlindedBeaconBlock::default())).await?; + let res = mock_validator.do_submit_block(Some(signed_blinded_block.clone())).await?; assert_eq!(res.status(), StatusCode::OK); assert_eq!(mock_state.received_submit_block(), 1); let response_body = serde_json::from_slice::(&res.bytes().await?)?; - assert_eq!(response_body.block_hash(), SubmitBlindedBlockResponse::default().block_hash()); + assert_eq!(response_body.block_hash(), signed_blinded_block.block_hash()); Ok(()) } @@ -54,7 +51,7 @@ async fn test_submit_block() -> Result<()> { async fn test_submit_block_too_large() -> Result<()> { setup_test_env(); let signer = random_secret(); - let pubkey: BlsPublicKey = blst_pubkey_to_alloy(&signer.sk_to_pk()).into(); + let pubkey = signer.public_key(); let chain = Chain::Holesky; let pbs_port = 3900; diff --git a/tests/tests/pbs_post_validators.rs b/tests/tests/pbs_post_validators.rs index 4c70ac01..8411941c 100644 --- a/tests/tests/pbs_post_validators.rs +++ b/tests/tests/pbs_post_validators.rs @@ -1,11 +1,7 @@ use std::{sync::Arc, time::Duration}; use alloy::rpc::types::beacon::relay::ValidatorRegistration; -use cb_common::{ - signer::{random_secret, BlsPublicKey}, - types::Chain, - utils::blst_pubkey_to_alloy, -}; +use cb_common::{pbs::BlsPublicKey, signer::random_secret, types::Chain}; use cb_pbs::{DefaultBuilderApi, PbsService, PbsState}; use cb_tests::{ mock_relay::{start_mock_relay_service, MockRelayState}, @@ -20,7 +16,7 @@ use tracing::info; async fn test_register_validators() -> Result<()> { setup_test_env(); let signer = random_secret(); - let pubkey: BlsPublicKey = blst_pubkey_to_alloy(&signer.sk_to_pk()).into(); + let pubkey: BlsPublicKey = signer.public_key(); let chain = Chain::Holesky; let pbs_port = 4000; @@ -66,7 +62,7 @@ async fn test_register_validators() -> Result<()> { async fn test_register_validators_returns_422_if_request_is_malformed() -> Result<()> { setup_test_env(); let signer = random_secret(); - let pubkey: BlsPublicKey = blst_pubkey_to_alloy(&signer.sk_to_pk()).into(); + let pubkey: BlsPublicKey = signer.public_key(); let chain = Chain::Holesky; let pbs_port = 4100; @@ -206,7 +202,7 @@ async fn test_register_validators_returns_422_if_request_is_malformed() -> Resul async fn test_register_validators_does_not_retry_on_429() -> Result<()> { setup_test_env(); let signer = random_secret(); - let pubkey: BlsPublicKey = blst_pubkey_to_alloy(&signer.sk_to_pk()).into(); + let pubkey: BlsPublicKey = signer.public_key(); let chain = Chain::Holesky; let pbs_port = 4200; @@ -259,7 +255,7 @@ async fn test_register_validators_does_not_retry_on_429() -> Result<()> { async fn test_register_validators_retries_on_500() -> Result<()> { setup_test_env(); let signer = random_secret(); - let pubkey: BlsPublicKey = blst_pubkey_to_alloy(&signer.sk_to_pk()).into(); + let pubkey: BlsPublicKey = signer.public_key(); let chain = Chain::Holesky; let pbs_port = 4300; diff --git a/tests/tests/signer_jwt_auth.rs b/tests/tests/signer_jwt_auth.rs index 90a0365f..090517bf 100644 --- a/tests/tests/signer_jwt_auth.rs +++ b/tests/tests/signer_jwt_auth.rs @@ -1,9 +1,10 @@ use std::{collections::HashMap, time::Duration}; -use alloy::{hex, primitives::FixedBytes}; +use alloy::hex; use cb_common::{ commit::{constants::GET_PUBKEYS_PATH, request::GetPubkeysResponse}, config::StartSignerConfig, + pbs::BlsPublicKey, signer::{SignerLoader, ValidatorKeysFormat}, types::{Chain, ModuleId}, utils::create_jwt, @@ -131,8 +132,8 @@ async fn verify_pubkeys(response: Response) -> Result<()> { let pubkey_json = response.json::().await?; assert_eq!(pubkey_json.keys.len(), 2); let expected_pubkeys = vec![ - FixedBytes::new(hex!("883827193f7627cd04e621e1e8d56498362a52b2a30c9a1c72036eb935c4278dee23d38a24d2f7dda62689886f0c39f4")), - FixedBytes::new(hex!("b3a22e4a673ac7a153ab5b3c17a4dbef55f7e47210b20c0cbb0e66df5b36bb49ef808577610b034172e955d2312a61b9")), + BlsPublicKey::deserialize(&hex!("883827193f7627cd04e621e1e8d56498362a52b2a30c9a1c72036eb935c4278dee23d38a24d2f7dda62689886f0c39f4")).unwrap(), + BlsPublicKey::deserialize(&hex!("b3a22e4a673ac7a153ab5b3c17a4dbef55f7e47210b20c0cbb0e66df5b36bb49ef808577610b034172e955d2312a61b9")).unwrap(), ]; for expected in expected_pubkeys { assert!( From f82e831b2c65ed1378152a0a8dc23725cee83d70 Mon Sep 17 00:00:00 2001 From: eltitanb Date: Thu, 10 Jul 2025 22:56:34 +0100 Subject: [PATCH 03/12] fix clippy + some tests --- benches/pbs/src/main.rs | 10 ++++------ crates/common/src/commit/request.rs | 6 +++--- crates/common/src/config/utils.rs | 5 +++-- crates/common/src/pbs/error.rs | 2 +- crates/common/src/signer/schemes/ecdsa.rs | 2 +- crates/common/src/utils.rs | 13 +++++++++++++ crates/pbs/src/mev_boost/get_header.rs | 11 +++++++---- examples/da_commit/src/main.rs | 2 +- tests/src/mock_validator.rs | 4 ++-- 9 files changed, 35 insertions(+), 20 deletions(-) diff --git a/benches/pbs/src/main.rs b/benches/pbs/src/main.rs index 923823ac..16ee0dd5 100644 --- a/benches/pbs/src/main.rs +++ b/benches/pbs/src/main.rs @@ -1,10 +1,11 @@ use std::time::{Duration, Instant}; -use alloy::{hex, primitives::B256}; +use alloy::primitives::B256; use cb_common::{ config::RelayConfig, pbs::{BlsPublicKey, BlsSecretKey, GetHeaderResponse, RelayClient, RelayEntry}, types::Chain, + utils::TestRandomSeed, }; use cb_tests::mock_relay::{start_mock_relay_service, MockRelayState}; use comfy_table::Table; @@ -16,9 +17,6 @@ mod config; fn get_random_hash() -> B256 { B256::from(rand::random::<[u8; 32]>()) } -fn get_random_pubkey() -> BlsPublicKey { - BlsPublicKey::deserialize(&hex!("0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")).unwrap() -} #[tokio::main] async fn main() { @@ -44,7 +42,7 @@ async fn main() { // bench for slot in 0..config.benchmark.n_slots { let parent_hash = get_random_hash(); - let validator_pubkey = get_random_pubkey(); + let validator_pubkey = BlsPublicKey::test_random(); let url = mock_validator.get_header_url(slot, &parent_hash, &validator_pubkey).unwrap(); for _ in 0..config.benchmark.headers_per_slot { @@ -150,7 +148,7 @@ async fn start_mock_relay(chain: Chain, relay_config: RelayConfig) { } fn get_mock_validator(bench: BenchConfig) -> RelayClient { - let entry = RelayEntry { id: bench.id, pubkey: get_random_pubkey(), url: bench.url }; + let entry = RelayEntry { id: bench.id, pubkey: BlsPublicKey::test_random(), url: bench.url }; let config = RelayConfig { entry, id: None, diff --git a/crates/common/src/commit/request.rs b/crates/common/src/commit/request.rs index a41b5648..c148dc93 100644 --- a/crates/common/src/commit/request.rs +++ b/crates/common/src/commit/request.rs @@ -261,7 +261,7 @@ mod tests { #[test] fn test_decode_response_signature() { - let data = r#""0xa3ffa9241f78279f1af04644cb8c79c2d8f02bcf0e28e2f186f6dcccac0a869c2be441fda50f0dea895cfce2e53f0989a3ffa9241f78279f1af04644cb8c79c2d8f02bcf0e28e2f186f6dcccac0a869c2be441fda50f0dea895cfce2e53f0989""#; + let data = r#""0xc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000""#; let _: BlsSignature = serde_json::from_str(data).unwrap(); let data = r#""0x985b495f49d1b96db3bba3f6c5dd1810950317c10d4c2042bd316f338cdbe74359072e209b85e56ac492092d7860063dd096ca31b4e164ef27e3f8d508e656801c""#; @@ -294,7 +294,7 @@ mod tests { "delegator": "0xa3366b54f28e4bf1461926a3c70cdb0ec432b5c92554ecaae3742d33fb33873990cbed1761c68020e6d3c14d30a22050", "proxy": "0xa3366b54f28e4bf1461926a3c70cdb0ec432b5c92554ecaae3742d33fb33873990cbed1761c68020e6d3c14d30a22050" }, - "signature": "0xa3ffa9241f78279f1af04644cb8c79c2d8f02bcf0e28e2f186f6dcccac0a869c2be441fda50f0dea895cfce2e53f0989a3ffa9241f78279f1af04644cb8c79c2d8f02bcf0e28e2f186f6dcccac0a869c2be441fda50f0dea895cfce2e53f0989" + "signature": "0xc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" }"#; let _: SignedProxyDelegationBls = serde_json::from_str(data).unwrap(); @@ -304,7 +304,7 @@ mod tests { "delegator": "0xa3366b54f28e4bf1461926a3c70cdb0ec432b5c92554ecaae3742d33fb33873990cbed1761c68020e6d3c14d30a22050", "proxy": "0x4ca9939a8311a7cab3dde201b70157285fa81a9d" }, - "signature": "0xa3ffa9241f78279f1af04644cb8c79c2d8f02bcf0e28e2f186f6dcccac0a869c2be441fda50f0dea895cfce2e53f0989a3ffa9241f78279f1af04644cb8c79c2d8f02bcf0e28e2f186f6dcccac0a869c2be441fda50f0dea895cfce2e53f0989" + "signature": "0xc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" }"#; let _: SignedProxyDelegationEcdsa = serde_json::from_str(data).unwrap(); diff --git a/crates/common/src/config/utils.rs b/crates/common/src/config/utils.rs index 84fd1a19..f99d9dc1 100644 --- a/crates/common/src/config/utils.rs +++ b/crates/common/src/config/utils.rs @@ -61,6 +61,7 @@ fn decode_string_to_map(raw: &str) -> Result> { #[cfg(test)] mod tests { use super::*; + use crate::utils::TestRandomSeed; #[test] fn test_decode_string_to_map() { @@ -74,8 +75,8 @@ mod tests { #[test] fn test_remove_duplicate_keys() { - let key1 = BlsPublicKey::deserialize(&[1; 48]).unwrap(); - let key2 = BlsPublicKey::deserialize(&[2; 48]).unwrap(); + let key1 = BlsPublicKey::test_random(); + let key2 = BlsPublicKey::test_random(); let keys = vec![key1.clone(), key2.clone(), key1.clone()]; let unique_keys = remove_duplicate_keys(keys); diff --git a/crates/common/src/pbs/error.rs b/crates/common/src/pbs/error.rs index 982d74f1..da6d0ace 100644 --- a/crates/common/src/pbs/error.rs +++ b/crates/common/src/pbs/error.rs @@ -55,7 +55,7 @@ pub enum ValidationError { EmptyBlockhash, #[error("pubkey mismatch: expected {expected} got {got}")] - PubkeyMismatch { expected: BlsPublicKey, got: BlsPublicKey }, + PubkeyMismatch { expected: Box, got: Box }, #[error("parent hash mismatch: expected {expected} got {got}")] ParentHashMismatch { expected: B256, got: B256 }, diff --git a/crates/common/src/signer/schemes/ecdsa.rs b/crates/common/src/signer/schemes/ecdsa.rs index 4f7d9892..f845e2f4 100644 --- a/crates/common/src/signer/schemes/ecdsa.rs +++ b/crates/common/src/signer/schemes/ecdsa.rs @@ -91,7 +91,7 @@ impl EcdsaSigner { match self { EcdsaSigner::Local(sk) => { let domain = compute_domain(chain, COMMIT_BOOST_DOMAIN); - let signing_root = compute_signing_root(object_root, domain).into(); + let signing_root = compute_signing_root(object_root, domain); sk.sign_hash_sync(&signing_root).map(EcdsaSignature::from) } } diff --git a/crates/common/src/utils.rs b/crates/common/src/utils.rs index 8c5c1721..402e867c 100644 --- a/crates/common/src/utils.rs +++ b/crates/common/src/utils.rs @@ -5,6 +5,7 @@ use std::{ use alloy::primitives::U256; use axum::http::HeaderValue; +use lh_types::test_utils::{SeedableRng, TestRandom, XorShiftRng}; use rand::{distr::Alphanumeric, Rng}; use reqwest::header::HeaderMap; use serde::{de::DeserializeOwned, Serialize}; @@ -347,6 +348,18 @@ pub async fn wait_for_signal() -> eyre::Result<()> { Ok(()) } +pub trait TestRandomSeed: TestRandom { + fn test_random() -> Self + where + Self: Sized, + { + let mut rng = XorShiftRng::from_seed([42; 16]); + Self::random_for_test(&mut rng) + } +} + +impl TestRandomSeed for T {} + #[cfg(test)] mod test { use super::{create_jwt, decode_jwt, validate_jwt}; diff --git a/crates/pbs/src/mev_boost/get_header.rs b/crates/pbs/src/mev_boost/get_header.rs index fc04c534..d066572d 100644 --- a/crates/pbs/src/mev_boost/get_header.rs +++ b/crates/pbs/src/mev_boost/get_header.rs @@ -460,14 +460,14 @@ fn validate_signature( ) -> Result<(), ValidationError> { if expected_relay_pubkey != received_relay_pubkey { return Err(ValidationError::PubkeyMismatch { - expected: expected_relay_pubkey.clone(), - got: received_relay_pubkey.clone(), + expected: Box::new(expected_relay_pubkey.clone()), + got: Box::new(received_relay_pubkey.clone()), }); } if !verify_signed_message( chain, - &received_relay_pubkey, + received_relay_pubkey, &message, signature, APPLICATION_BUILDER_DOMAIN, @@ -595,7 +595,10 @@ mod tests { assert_eq!( validate_signature(Chain::Holesky, &wrong_pubkey, &pubkey, &message, &wrong_signature), - Err(ValidationError::PubkeyMismatch { expected: wrong_pubkey, got: pubkey.clone() }) + Err(ValidationError::PubkeyMismatch { + expected: Box::new(wrong_pubkey), + got: Box::new(pubkey.clone()) + }) ); assert!(matches!( diff --git a/examples/da_commit/src/main.rs b/examples/da_commit/src/main.rs index 7db8c255..27b5ce86 100644 --- a/examples/da_commit/src/main.rs +++ b/examples/da_commit/src/main.rs @@ -69,7 +69,7 @@ impl DaCommitService { let mut data = 0; loop { - self.send_request(data, pubkey.clone(), proxy_bls.clone(), proxy_ecdsa.clone()).await?; + self.send_request(data, pubkey.clone(), proxy_bls.clone(), proxy_ecdsa).await?; sleep(Duration::from_secs(self.config.extra.sleep_secs)).await; data += 1; } diff --git a/tests/src/mock_validator.rs b/tests/src/mock_validator.rs index bb50c0ff..3c898ad7 100644 --- a/tests/src/mock_validator.rs +++ b/tests/src/mock_validator.rs @@ -46,7 +46,7 @@ impl MockValidator { let url = self.comm_boost.submit_block_url().unwrap(); let signed_blinded_block = - signed_blinded_block.unwrap_or_else(|| load_test_signed_blinded_block()); + signed_blinded_block.unwrap_or_else(load_test_signed_blinded_block); Ok(self.comm_boost.client.post(url).json(&signed_blinded_block).send().await?) } @@ -54,5 +54,5 @@ impl MockValidator { pub fn load_test_signed_blinded_block() -> SignedBlindedBeaconBlock { let data_json = include_str!("signed-blinded-beacon-block-electra-2.json"); - serde_json::from_str(&data_json).unwrap() + serde_json::from_str(data_json).unwrap() } From 5de891ce111ec05ced8465249305d1fd0819d1c2 Mon Sep 17 00:00:00 2001 From: eltitanb Date: Fri, 11 Jul 2025 11:35:22 +0100 Subject: [PATCH 04/12] fix tests --- .../signed-blinded-beacon-block-deneb-2.json | 307 --- .../signed-blinded-beacon-block-deneb.json | 307 --- tests/data/signed_blinded_block_holesky.json | 2135 +---------------- 3 files changed, 64 insertions(+), 2685 deletions(-) delete mode 100644 crates/common/src/pbs/types/testdata/signed-blinded-beacon-block-deneb-2.json delete mode 100644 crates/common/src/pbs/types/testdata/signed-blinded-beacon-block-deneb.json diff --git a/crates/common/src/pbs/types/testdata/signed-blinded-beacon-block-deneb-2.json b/crates/common/src/pbs/types/testdata/signed-blinded-beacon-block-deneb-2.json deleted file mode 100644 index 7ba61e3b..00000000 --- a/crates/common/src/pbs/types/testdata/signed-blinded-beacon-block-deneb-2.json +++ /dev/null @@ -1,307 +0,0 @@ -{ - "message": { - "slot": "348241", - "proposer_index": "35822", - "parent_root": "0x15bd2273ad32344e34f842fc77ad8acb2a2eaedafa6e5328ef799babfe81113d", - "state_root": "0x4f6e0857501da4ab1d72f0c122869e1c084e16daa96613b64914aada28d0dc28", - "body": { - "randao_reveal": "0xb2b7d2e89bb4a4aa6a377972651bb9041cb59af8eedd19568d699fc0866189d3fd78cc93c0e63877b7e2bd6d34d1597c0afd4508aa99b6e882c2cb1ac6f424adba29afd46d1737124300ad72177715fcce8584dd25a06c45bfe9a8ccabd6175d", - "eth1_data": { - "deposit_root": "0x704964a5ad034a440f4f29ff1875986db66adbca45dc0014e439349c7e10194f", - "deposit_count": "4933", - "block_hash": "0x9c69de2814a7c3e3751654511372937627dacc3187bf457892789f3f5533c794" - }, - "graffiti": "0x74656b752d626573750000000000000000000000000000000000000000000000", - "proposer_slashings": [], - "attester_slashings": [], - "attestations": [ - { - "aggregation_bits": "0xffffffffffffffffffffffffffffff5fff", - "data": { - "slot": "348240", - "index": "7", - "beacon_block_root": "0x15bd2273ad32344e34f842fc77ad8acb2a2eaedafa6e5328ef799babfe81113d", - "source": { - "epoch": "10881", - "root": "0x12a21e7bb91e09dac76d5d3f170db6358785032f10b9130a1e92e6f4409f2ecf" - }, - "target": { - "epoch": "10882", - "root": "0x1c8a9a3a0d4c9d72a93b9ff2ea442a986f4d6dfde52953e48a146206393e7708" - } - }, - "signature": "0x92da7bf78eb364219f85af2388d7ac7ddbea1934786d75875486ec9fceb310eee131dcfea131bdf4593d3c431b31b2900bb48ebb7ab02e17524d86a4e132883246df8ce427e935dd9e20c422cdf8eb135b3cc45b86fe4c2f592fb4899eb22f7c" - }, - { - "aggregation_bits": "0xffdffffffffffff5fffffffffffffffffd", - "data": { - "slot": "348240", - "index": "3", - "beacon_block_root": "0x15bd2273ad32344e34f842fc77ad8acb2a2eaedafa6e5328ef799babfe81113d", - "source": { - "epoch": "10881", - "root": "0x12a21e7bb91e09dac76d5d3f170db6358785032f10b9130a1e92e6f4409f2ecf" - }, - "target": { - "epoch": "10882", - "root": "0x1c8a9a3a0d4c9d72a93b9ff2ea442a986f4d6dfde52953e48a146206393e7708" - } - }, - "signature": "0x88cce1f9fbf651e52a6ab71dea2f4025702021744aac90fb2997f82bac6c192e295ae39b2a430546cb102bf8b68f687e0f40a5179bc293e1424e37d694ef1ad6b3b8de72a0e7fbbe97aeafe6f47e949d415381fbbb090e3135224d5b324eefcb" - }, - { - "aggregation_bits": "0xffffffffffefffffffffbfffff7fffdfff", - "data": { - "slot": "348240", - "index": "11", - "beacon_block_root": "0x15bd2273ad32344e34f842fc77ad8acb2a2eaedafa6e5328ef799babfe81113d", - "source": { - "epoch": "10881", - "root": "0x12a21e7bb91e09dac76d5d3f170db6358785032f10b9130a1e92e6f4409f2ecf" - }, - "target": { - "epoch": "10882", - "root": "0x1c8a9a3a0d4c9d72a93b9ff2ea442a986f4d6dfde52953e48a146206393e7708" - } - }, - "signature": "0x82186d946dfde2ab3b5fcf5bd858fadeec7fa9729f28527e209d16a1d9b4d635558cad6f8de8cee12caa2a4fc5459fb911ca17cbbecfd22e83c82e244ad7a8c8c849a1e03ee88bf0d338c633c2acfefd142574897cd78f9076b69f6e370e3751" - }, - { - "aggregation_bits": "0xfffdffffffffffffffffffffffffffffff", - "data": { - "slot": "348240", - "index": "4", - "beacon_block_root": "0x15bd2273ad32344e34f842fc77ad8acb2a2eaedafa6e5328ef799babfe81113d", - "source": { - "epoch": "10881", - "root": "0x12a21e7bb91e09dac76d5d3f170db6358785032f10b9130a1e92e6f4409f2ecf" - }, - "target": { - "epoch": "10882", - "root": "0x1c8a9a3a0d4c9d72a93b9ff2ea442a986f4d6dfde52953e48a146206393e7708" - } - }, - "signature": "0xb9c5ee50f800fe2619d1d0fe46a2fb00a64bcf2613e46a40b579ce6a39c4f6cd71a46790757ccc3df8f5f82e34c77c8d084f525ea8a4bd5bd10190496644be0740ace3d217e43af15229a8023d58e583cfec849fab10169225444f4f4ecc66a8" - }, - { - "aggregation_bits": "0xffffffffeffffffffffffdffffffffffff", - "data": { - "slot": "348240", - "index": "12", - "beacon_block_root": "0x15bd2273ad32344e34f842fc77ad8acb2a2eaedafa6e5328ef799babfe81113d", - "source": { - "epoch": "10881", - "root": "0x12a21e7bb91e09dac76d5d3f170db6358785032f10b9130a1e92e6f4409f2ecf" - }, - "target": { - "epoch": "10882", - "root": "0x1c8a9a3a0d4c9d72a93b9ff2ea442a986f4d6dfde52953e48a146206393e7708" - } - }, - "signature": "0x91e4ee5c0d6bb54d6856cee653c6859f635cebf9c51bef524d6f439cf6d1c69bea5fcb3e4c067c178cfa4518a76baba909b18189a864f38020f44b2cd5223a11e42d58aaedfa2f004710a72a704357874850842a1493017eca6e473d01395932" - }, - { - "aggregation_bits": "0xffffffffffffffffffffffffffffffffff", - "data": { - "slot": "348240", - "index": "13", - "beacon_block_root": "0x15bd2273ad32344e34f842fc77ad8acb2a2eaedafa6e5328ef799babfe81113d", - "source": { - "epoch": "10881", - "root": "0x12a21e7bb91e09dac76d5d3f170db6358785032f10b9130a1e92e6f4409f2ecf" - }, - "target": { - "epoch": "10882", - "root": "0x1c8a9a3a0d4c9d72a93b9ff2ea442a986f4d6dfde52953e48a146206393e7708" - } - }, - "signature": "0x8c376c5bb5ada745ba8cb8ce2aae103f4e3f85549ceaacaf312b1fa8e6d2ee5232149a926dcfd58ffa1f50f710eb4edc10943bbd40a601f2fb4d53104a59c0663a397744b59f1fa0744bba49f22afc3bab47045ebb42e61dac41ad44c6bf28f4" - }, - { - "aggregation_bits": "0xfffffffffffffffffffffffffffeffffff", - "data": { - "slot": "348240", - "index": "1", - "beacon_block_root": "0x15bd2273ad32344e34f842fc77ad8acb2a2eaedafa6e5328ef799babfe81113d", - "source": { - "epoch": "10881", - "root": "0x12a21e7bb91e09dac76d5d3f170db6358785032f10b9130a1e92e6f4409f2ecf" - }, - "target": { - "epoch": "10882", - "root": "0x1c8a9a3a0d4c9d72a93b9ff2ea442a986f4d6dfde52953e48a146206393e7708" - } - }, - "signature": "0xaf11c64ce957f2a1686d12b07d0fbc170d89e48490e326cd73ef761ba042bddc01e48e5fc39953c6113df0a989d75e750d5b9d75155259508c2bbdd53903967f893e24f2f7f751f4a05b0fb1cb2b9084ce8543690a8a623599308d6c190fca4a" - }, - { - "aggregation_bits": "0xfffffff5fffffffffdfffbbffffff7ffff", - "data": { - "slot": "348240", - "index": "6", - "beacon_block_root": "0x15bd2273ad32344e34f842fc77ad8acb2a2eaedafa6e5328ef799babfe81113d", - "source": { - "epoch": "10881", - "root": "0x12a21e7bb91e09dac76d5d3f170db6358785032f10b9130a1e92e6f4409f2ecf" - }, - "target": { - "epoch": "10882", - "root": "0x1c8a9a3a0d4c9d72a93b9ff2ea442a986f4d6dfde52953e48a146206393e7708" - } - }, - "signature": "0x91075da401796a4341ab9a850ff330c9b0d996ca12b9970ec15a4b40fee652edd043e0c9f9d81529621b3a7970e676f619d7a39af67bf193af4441b5447f199f02d75a26c32181569cddc0a237b7064971539f80811fe40e9362d4d9242404ed" - }, - { - "aggregation_bits": "0xfffffffdfffffffffffffdfffffeffffff", - "data": { - "slot": "348240", - "index": "0", - "beacon_block_root": "0x15bd2273ad32344e34f842fc77ad8acb2a2eaedafa6e5328ef799babfe81113d", - "source": { - "epoch": "10881", - "root": "0x12a21e7bb91e09dac76d5d3f170db6358785032f10b9130a1e92e6f4409f2ecf" - }, - "target": { - "epoch": "10882", - "root": "0x1c8a9a3a0d4c9d72a93b9ff2ea442a986f4d6dfde52953e48a146206393e7708" - } - }, - "signature": "0xad9aa5aa9b9c022036fbb81a0aca626b19a2ccd7c7ee6efa5b2a454f5ffb5d75d00e5563b31319b3a0ad1e0ef6f512be00fb8c39243004a1133610344473953dfcf06c3bd53f00255de6983927acd8624b0131fe9d8a085062747d70972b4713" - }, - { - "aggregation_bits": "0xffffffffffff7fdfffffffffffffffffff", - "data": { - "slot": "348240", - "index": "2", - "beacon_block_root": "0x15bd2273ad32344e34f842fc77ad8acb2a2eaedafa6e5328ef799babfe81113d", - "source": { - "epoch": "10881", - "root": "0x12a21e7bb91e09dac76d5d3f170db6358785032f10b9130a1e92e6f4409f2ecf" - }, - "target": { - "epoch": "10882", - "root": "0x1c8a9a3a0d4c9d72a93b9ff2ea442a986f4d6dfde52953e48a146206393e7708" - } - }, - "signature": "0x89dde857bc31a4cc5e71d6cc440c00b2b1ee85b758722aadc5c4da0a939523de7532aabcfef4e80f84094924bb69d80d0a3d702b85859c5fce0433b6d0f7bc302af866ef7a9234a75be7bbd91b32256126808ffdf65ac0ce07a33afbaa16c575" - }, - { - "aggregation_bits": "0xffffffffffffffffffffffffffffffffff", - "data": { - "slot": "348240", - "index": "8", - "beacon_block_root": "0x15bd2273ad32344e34f842fc77ad8acb2a2eaedafa6e5328ef799babfe81113d", - "source": { - "epoch": "10881", - "root": "0x12a21e7bb91e09dac76d5d3f170db6358785032f10b9130a1e92e6f4409f2ecf" - }, - "target": { - "epoch": "10882", - "root": "0x1c8a9a3a0d4c9d72a93b9ff2ea442a986f4d6dfde52953e48a146206393e7708" - } - }, - "signature": "0x891fbba500eee2cf2f5734d3bf8445e8684376e47469692d44e87fc8a295616d9f29410afc2d6ff2bc649618b33b417e13de4e152099aac054f4d35df4cd79234b6df1edcf2393b7ebc0f2ecf61f4604232b96830e0dbff9311408dad4479667" - }, - { - "aggregation_bits": "0xfffffffffffbffffffffefffffffff5fff", - "data": { - "slot": "348240", - "index": "14", - "beacon_block_root": "0x15bd2273ad32344e34f842fc77ad8acb2a2eaedafa6e5328ef799babfe81113d", - "source": { - "epoch": "10881", - "root": "0x12a21e7bb91e09dac76d5d3f170db6358785032f10b9130a1e92e6f4409f2ecf" - }, - "target": { - "epoch": "10882", - "root": "0x1c8a9a3a0d4c9d72a93b9ff2ea442a986f4d6dfde52953e48a146206393e7708" - } - }, - "signature": "0xb9ab0354d0d61eb6b5f2184dc3bd0c8416cca74f2c913c6aaca653a87dd2c4b8ba2471aa450e0fa170573637c49dc8920eb84970fea4230d7b3c3c8c8152c782e912b29bc19a6de05dc36c1b44db2f649f31673b4751e1b22f17021833ca9cc8" - }, - { - "aggregation_bits": "0xfffffebffffbf7ffeffffbffffffffffff", - "data": { - "slot": "348240", - "index": "5", - "beacon_block_root": "0x15bd2273ad32344e34f842fc77ad8acb2a2eaedafa6e5328ef799babfe81113d", - "source": { - "epoch": "10881", - "root": "0x12a21e7bb91e09dac76d5d3f170db6358785032f10b9130a1e92e6f4409f2ecf" - }, - "target": { - "epoch": "10882", - "root": "0x1c8a9a3a0d4c9d72a93b9ff2ea442a986f4d6dfde52953e48a146206393e7708" - } - }, - "signature": "0x8e17aa835e6343f708e73e432b7268741f60565f5bb6ef62b5fba892438ca5474a14c0382609e14624058f3fab120e8902ad3f667cf14418836ce120f3bbf50ea3c15923c881e599227cc3a2758ef9a2cd08bd3b862bd711a875e27477ac347c" - }, - { - "aggregation_bits": "0xfffffffffffefffffffffffeffffffffff", - "data": { - "slot": "348240", - "index": "10", - "beacon_block_root": "0x15bd2273ad32344e34f842fc77ad8acb2a2eaedafa6e5328ef799babfe81113d", - "source": { - "epoch": "10881", - "root": "0x12a21e7bb91e09dac76d5d3f170db6358785032f10b9130a1e92e6f4409f2ecf" - }, - "target": { - "epoch": "10882", - "root": "0x1c8a9a3a0d4c9d72a93b9ff2ea442a986f4d6dfde52953e48a146206393e7708" - } - }, - "signature": "0xa0909f67a7745300cee6278605e3cb79e5a9564cd6e81ac379b285e0eb6e1849537326b546079d7bf676c8e33a166cad00ab74a396f12c9f4851fb64612f6aeb911db550e0aeae88e1b90831a5a858ae64f9262f67403327d85fcb345df9fca4" - }, - { - "aggregation_bits": "0xffffffffffffffffffffffffffffffffff", - "data": { - "slot": "348240", - "index": "9", - "beacon_block_root": "0x15bd2273ad32344e34f842fc77ad8acb2a2eaedafa6e5328ef799babfe81113d", - "source": { - "epoch": "10881", - "root": "0x12a21e7bb91e09dac76d5d3f170db6358785032f10b9130a1e92e6f4409f2ecf" - }, - "target": { - "epoch": "10882", - "root": "0x1c8a9a3a0d4c9d72a93b9ff2ea442a986f4d6dfde52953e48a146206393e7708" - } - }, - "signature": "0x886d038ddd7598cfda720dfe1caf83e030e24b207bbc0c97d012fbf5accbaa2f63366f32fe643aa1fdf6c8282480cd51165710bb786d77ecfb72ef7cc9d55e342c94fb57f5a75d50a0d486ecdf014bb08e0195f24202911c86efb5b46b2167ab" - } - ], - "deposits": [], - "voluntary_exits": [], - "sync_aggregate": { - "sync_committee_bits": "0xffffffffffffffffffff7edfffffffff7ffffffffffffffffffffffffffff7ffdf7ffffffff7fffffefffffffffffffbfffffffffdffffffffffffffffffffff", - "sync_committee_signature": "0x877de19f5fff89de5af36954d4c7f7f5c2ccf6f8dc39fe7e3eb87c3357fca26f0af747dffd0f992c8844a20763e9f8a51858d0be70ce610055c6421d340160adec0ddcb706a7d7a5c45edff7b5f9b9a039fce093cea41c7a5699834f9de48b94" - }, - "execution_payload_header": { - "parent_hash": "0xa330251430b91a6fb5342f30a1f527dc76499c03a411464235951dbd51b94d9f", - "fee_recipient": "0xf97e180c050e5ab072211ad2c213eb5aee4df134", - "state_root": "0x079f2cc22a29388fd4fc20f451cbaa3ff39845d68b2c368ff7be314617418e38", - "receipts_root": "0xed980a4cf6df8ba330c14ed9fe0597ec20515f44e5a9adfd2f7b72aa14890996", - "logs_bloom": "0x0000000400000008000008000040000000000000000000001000104880000200000004000000400000000204000020002000000000000000000000000022000800000004000000000002000c000000000000000000000100000000000000000000000000000000000000000000000040000000000040000001000014000000010002104000000000000000000000000000000000000000000000000000000080020000000000000000002400000000000001000000000002000200102000000040100002000000000000000000000000000000000000000800000000000000000010000000000000000000000000000000000400002000000000000000200000", - "prev_randao": "0x86cc02ef030b0c147321a7f94158c1b33cb730f8baac3c59955b983fda3ae39b", - "block_number": "330714", - "gas_limit": "30000000", - "gas_used": "369098", - "timestamp": "1679442492", - "extra_data": "0x", - "base_fee_per_gas": "7", - "block_hash": "0x4ab1ced57222819bf6a6b6c1456715011585599a1cef18b060eb364811bbb14e", - "transactions_root": "0x6d47bae3b4963cbde00ec39bbd6442540afe26f8005e73722489904836008bfc", - "withdrawals_root": "0x5dc5f3ff8bade8e1dd04e5cf56292b2a194a2829e1c8e8b4a627d95e08296ba3", - "blob_gas_used": "4438756708366371443", - "excess_blob_gas": "12504111653614393862" - }, - "bls_to_execution_changes": [], - "blob_kzg_commitments": [ - "0x95cc5099bbd8420d8ebade383c00a2346dace60a7604f768cd71501757b4d72eeb7d5474a6b615af10379d69aa9f478f", - "0xae9f2d2217013ef61f995f9074faead9ec24e8048440164ec3d6029b87d43686dd0c97c2df9554fc997d0d66c3a78929" - ] - } - }, - "signature": "0x8c3095fd9d3a18e43ceeb7648281e16bb03044839dffea796432c4e5a1372bef22c11a98a31e0c1c5389b98cc6d45917170a0f1634bcf152d896f360dc599fabba2ec4de77898b5dff080fa1628482bdbad5b37d2e64fea3d8721095186cfe50" -} \ No newline at end of file diff --git a/crates/common/src/pbs/types/testdata/signed-blinded-beacon-block-deneb.json b/crates/common/src/pbs/types/testdata/signed-blinded-beacon-block-deneb.json deleted file mode 100644 index 7ba61e3b..00000000 --- a/crates/common/src/pbs/types/testdata/signed-blinded-beacon-block-deneb.json +++ /dev/null @@ -1,307 +0,0 @@ -{ - "message": { - "slot": "348241", - "proposer_index": "35822", - "parent_root": "0x15bd2273ad32344e34f842fc77ad8acb2a2eaedafa6e5328ef799babfe81113d", - "state_root": "0x4f6e0857501da4ab1d72f0c122869e1c084e16daa96613b64914aada28d0dc28", - "body": { - "randao_reveal": "0xb2b7d2e89bb4a4aa6a377972651bb9041cb59af8eedd19568d699fc0866189d3fd78cc93c0e63877b7e2bd6d34d1597c0afd4508aa99b6e882c2cb1ac6f424adba29afd46d1737124300ad72177715fcce8584dd25a06c45bfe9a8ccabd6175d", - "eth1_data": { - "deposit_root": "0x704964a5ad034a440f4f29ff1875986db66adbca45dc0014e439349c7e10194f", - "deposit_count": "4933", - "block_hash": "0x9c69de2814a7c3e3751654511372937627dacc3187bf457892789f3f5533c794" - }, - "graffiti": "0x74656b752d626573750000000000000000000000000000000000000000000000", - "proposer_slashings": [], - "attester_slashings": [], - "attestations": [ - { - "aggregation_bits": "0xffffffffffffffffffffffffffffff5fff", - "data": { - "slot": "348240", - "index": "7", - "beacon_block_root": "0x15bd2273ad32344e34f842fc77ad8acb2a2eaedafa6e5328ef799babfe81113d", - "source": { - "epoch": "10881", - "root": "0x12a21e7bb91e09dac76d5d3f170db6358785032f10b9130a1e92e6f4409f2ecf" - }, - "target": { - "epoch": "10882", - "root": "0x1c8a9a3a0d4c9d72a93b9ff2ea442a986f4d6dfde52953e48a146206393e7708" - } - }, - "signature": "0x92da7bf78eb364219f85af2388d7ac7ddbea1934786d75875486ec9fceb310eee131dcfea131bdf4593d3c431b31b2900bb48ebb7ab02e17524d86a4e132883246df8ce427e935dd9e20c422cdf8eb135b3cc45b86fe4c2f592fb4899eb22f7c" - }, - { - "aggregation_bits": "0xffdffffffffffff5fffffffffffffffffd", - "data": { - "slot": "348240", - "index": "3", - "beacon_block_root": "0x15bd2273ad32344e34f842fc77ad8acb2a2eaedafa6e5328ef799babfe81113d", - "source": { - "epoch": "10881", - "root": "0x12a21e7bb91e09dac76d5d3f170db6358785032f10b9130a1e92e6f4409f2ecf" - }, - "target": { - "epoch": "10882", - "root": "0x1c8a9a3a0d4c9d72a93b9ff2ea442a986f4d6dfde52953e48a146206393e7708" - } - }, - "signature": "0x88cce1f9fbf651e52a6ab71dea2f4025702021744aac90fb2997f82bac6c192e295ae39b2a430546cb102bf8b68f687e0f40a5179bc293e1424e37d694ef1ad6b3b8de72a0e7fbbe97aeafe6f47e949d415381fbbb090e3135224d5b324eefcb" - }, - { - "aggregation_bits": "0xffffffffffefffffffffbfffff7fffdfff", - "data": { - "slot": "348240", - "index": "11", - "beacon_block_root": "0x15bd2273ad32344e34f842fc77ad8acb2a2eaedafa6e5328ef799babfe81113d", - "source": { - "epoch": "10881", - "root": "0x12a21e7bb91e09dac76d5d3f170db6358785032f10b9130a1e92e6f4409f2ecf" - }, - "target": { - "epoch": "10882", - "root": "0x1c8a9a3a0d4c9d72a93b9ff2ea442a986f4d6dfde52953e48a146206393e7708" - } - }, - "signature": "0x82186d946dfde2ab3b5fcf5bd858fadeec7fa9729f28527e209d16a1d9b4d635558cad6f8de8cee12caa2a4fc5459fb911ca17cbbecfd22e83c82e244ad7a8c8c849a1e03ee88bf0d338c633c2acfefd142574897cd78f9076b69f6e370e3751" - }, - { - "aggregation_bits": "0xfffdffffffffffffffffffffffffffffff", - "data": { - "slot": "348240", - "index": "4", - "beacon_block_root": "0x15bd2273ad32344e34f842fc77ad8acb2a2eaedafa6e5328ef799babfe81113d", - "source": { - "epoch": "10881", - "root": "0x12a21e7bb91e09dac76d5d3f170db6358785032f10b9130a1e92e6f4409f2ecf" - }, - "target": { - "epoch": "10882", - "root": "0x1c8a9a3a0d4c9d72a93b9ff2ea442a986f4d6dfde52953e48a146206393e7708" - } - }, - "signature": "0xb9c5ee50f800fe2619d1d0fe46a2fb00a64bcf2613e46a40b579ce6a39c4f6cd71a46790757ccc3df8f5f82e34c77c8d084f525ea8a4bd5bd10190496644be0740ace3d217e43af15229a8023d58e583cfec849fab10169225444f4f4ecc66a8" - }, - { - "aggregation_bits": "0xffffffffeffffffffffffdffffffffffff", - "data": { - "slot": "348240", - "index": "12", - "beacon_block_root": "0x15bd2273ad32344e34f842fc77ad8acb2a2eaedafa6e5328ef799babfe81113d", - "source": { - "epoch": "10881", - "root": "0x12a21e7bb91e09dac76d5d3f170db6358785032f10b9130a1e92e6f4409f2ecf" - }, - "target": { - "epoch": "10882", - "root": "0x1c8a9a3a0d4c9d72a93b9ff2ea442a986f4d6dfde52953e48a146206393e7708" - } - }, - "signature": "0x91e4ee5c0d6bb54d6856cee653c6859f635cebf9c51bef524d6f439cf6d1c69bea5fcb3e4c067c178cfa4518a76baba909b18189a864f38020f44b2cd5223a11e42d58aaedfa2f004710a72a704357874850842a1493017eca6e473d01395932" - }, - { - "aggregation_bits": "0xffffffffffffffffffffffffffffffffff", - "data": { - "slot": "348240", - "index": "13", - "beacon_block_root": "0x15bd2273ad32344e34f842fc77ad8acb2a2eaedafa6e5328ef799babfe81113d", - "source": { - "epoch": "10881", - "root": "0x12a21e7bb91e09dac76d5d3f170db6358785032f10b9130a1e92e6f4409f2ecf" - }, - "target": { - "epoch": "10882", - "root": "0x1c8a9a3a0d4c9d72a93b9ff2ea442a986f4d6dfde52953e48a146206393e7708" - } - }, - "signature": "0x8c376c5bb5ada745ba8cb8ce2aae103f4e3f85549ceaacaf312b1fa8e6d2ee5232149a926dcfd58ffa1f50f710eb4edc10943bbd40a601f2fb4d53104a59c0663a397744b59f1fa0744bba49f22afc3bab47045ebb42e61dac41ad44c6bf28f4" - }, - { - "aggregation_bits": "0xfffffffffffffffffffffffffffeffffff", - "data": { - "slot": "348240", - "index": "1", - "beacon_block_root": "0x15bd2273ad32344e34f842fc77ad8acb2a2eaedafa6e5328ef799babfe81113d", - "source": { - "epoch": "10881", - "root": "0x12a21e7bb91e09dac76d5d3f170db6358785032f10b9130a1e92e6f4409f2ecf" - }, - "target": { - "epoch": "10882", - "root": "0x1c8a9a3a0d4c9d72a93b9ff2ea442a986f4d6dfde52953e48a146206393e7708" - } - }, - "signature": "0xaf11c64ce957f2a1686d12b07d0fbc170d89e48490e326cd73ef761ba042bddc01e48e5fc39953c6113df0a989d75e750d5b9d75155259508c2bbdd53903967f893e24f2f7f751f4a05b0fb1cb2b9084ce8543690a8a623599308d6c190fca4a" - }, - { - "aggregation_bits": "0xfffffff5fffffffffdfffbbffffff7ffff", - "data": { - "slot": "348240", - "index": "6", - "beacon_block_root": "0x15bd2273ad32344e34f842fc77ad8acb2a2eaedafa6e5328ef799babfe81113d", - "source": { - "epoch": "10881", - "root": "0x12a21e7bb91e09dac76d5d3f170db6358785032f10b9130a1e92e6f4409f2ecf" - }, - "target": { - "epoch": "10882", - "root": "0x1c8a9a3a0d4c9d72a93b9ff2ea442a986f4d6dfde52953e48a146206393e7708" - } - }, - "signature": "0x91075da401796a4341ab9a850ff330c9b0d996ca12b9970ec15a4b40fee652edd043e0c9f9d81529621b3a7970e676f619d7a39af67bf193af4441b5447f199f02d75a26c32181569cddc0a237b7064971539f80811fe40e9362d4d9242404ed" - }, - { - "aggregation_bits": "0xfffffffdfffffffffffffdfffffeffffff", - "data": { - "slot": "348240", - "index": "0", - "beacon_block_root": "0x15bd2273ad32344e34f842fc77ad8acb2a2eaedafa6e5328ef799babfe81113d", - "source": { - "epoch": "10881", - "root": "0x12a21e7bb91e09dac76d5d3f170db6358785032f10b9130a1e92e6f4409f2ecf" - }, - "target": { - "epoch": "10882", - "root": "0x1c8a9a3a0d4c9d72a93b9ff2ea442a986f4d6dfde52953e48a146206393e7708" - } - }, - "signature": "0xad9aa5aa9b9c022036fbb81a0aca626b19a2ccd7c7ee6efa5b2a454f5ffb5d75d00e5563b31319b3a0ad1e0ef6f512be00fb8c39243004a1133610344473953dfcf06c3bd53f00255de6983927acd8624b0131fe9d8a085062747d70972b4713" - }, - { - "aggregation_bits": "0xffffffffffff7fdfffffffffffffffffff", - "data": { - "slot": "348240", - "index": "2", - "beacon_block_root": "0x15bd2273ad32344e34f842fc77ad8acb2a2eaedafa6e5328ef799babfe81113d", - "source": { - "epoch": "10881", - "root": "0x12a21e7bb91e09dac76d5d3f170db6358785032f10b9130a1e92e6f4409f2ecf" - }, - "target": { - "epoch": "10882", - "root": "0x1c8a9a3a0d4c9d72a93b9ff2ea442a986f4d6dfde52953e48a146206393e7708" - } - }, - "signature": "0x89dde857bc31a4cc5e71d6cc440c00b2b1ee85b758722aadc5c4da0a939523de7532aabcfef4e80f84094924bb69d80d0a3d702b85859c5fce0433b6d0f7bc302af866ef7a9234a75be7bbd91b32256126808ffdf65ac0ce07a33afbaa16c575" - }, - { - "aggregation_bits": "0xffffffffffffffffffffffffffffffffff", - "data": { - "slot": "348240", - "index": "8", - "beacon_block_root": "0x15bd2273ad32344e34f842fc77ad8acb2a2eaedafa6e5328ef799babfe81113d", - "source": { - "epoch": "10881", - "root": "0x12a21e7bb91e09dac76d5d3f170db6358785032f10b9130a1e92e6f4409f2ecf" - }, - "target": { - "epoch": "10882", - "root": "0x1c8a9a3a0d4c9d72a93b9ff2ea442a986f4d6dfde52953e48a146206393e7708" - } - }, - "signature": "0x891fbba500eee2cf2f5734d3bf8445e8684376e47469692d44e87fc8a295616d9f29410afc2d6ff2bc649618b33b417e13de4e152099aac054f4d35df4cd79234b6df1edcf2393b7ebc0f2ecf61f4604232b96830e0dbff9311408dad4479667" - }, - { - "aggregation_bits": "0xfffffffffffbffffffffefffffffff5fff", - "data": { - "slot": "348240", - "index": "14", - "beacon_block_root": "0x15bd2273ad32344e34f842fc77ad8acb2a2eaedafa6e5328ef799babfe81113d", - "source": { - "epoch": "10881", - "root": "0x12a21e7bb91e09dac76d5d3f170db6358785032f10b9130a1e92e6f4409f2ecf" - }, - "target": { - "epoch": "10882", - "root": "0x1c8a9a3a0d4c9d72a93b9ff2ea442a986f4d6dfde52953e48a146206393e7708" - } - }, - "signature": "0xb9ab0354d0d61eb6b5f2184dc3bd0c8416cca74f2c913c6aaca653a87dd2c4b8ba2471aa450e0fa170573637c49dc8920eb84970fea4230d7b3c3c8c8152c782e912b29bc19a6de05dc36c1b44db2f649f31673b4751e1b22f17021833ca9cc8" - }, - { - "aggregation_bits": "0xfffffebffffbf7ffeffffbffffffffffff", - "data": { - "slot": "348240", - "index": "5", - "beacon_block_root": "0x15bd2273ad32344e34f842fc77ad8acb2a2eaedafa6e5328ef799babfe81113d", - "source": { - "epoch": "10881", - "root": "0x12a21e7bb91e09dac76d5d3f170db6358785032f10b9130a1e92e6f4409f2ecf" - }, - "target": { - "epoch": "10882", - "root": "0x1c8a9a3a0d4c9d72a93b9ff2ea442a986f4d6dfde52953e48a146206393e7708" - } - }, - "signature": "0x8e17aa835e6343f708e73e432b7268741f60565f5bb6ef62b5fba892438ca5474a14c0382609e14624058f3fab120e8902ad3f667cf14418836ce120f3bbf50ea3c15923c881e599227cc3a2758ef9a2cd08bd3b862bd711a875e27477ac347c" - }, - { - "aggregation_bits": "0xfffffffffffefffffffffffeffffffffff", - "data": { - "slot": "348240", - "index": "10", - "beacon_block_root": "0x15bd2273ad32344e34f842fc77ad8acb2a2eaedafa6e5328ef799babfe81113d", - "source": { - "epoch": "10881", - "root": "0x12a21e7bb91e09dac76d5d3f170db6358785032f10b9130a1e92e6f4409f2ecf" - }, - "target": { - "epoch": "10882", - "root": "0x1c8a9a3a0d4c9d72a93b9ff2ea442a986f4d6dfde52953e48a146206393e7708" - } - }, - "signature": "0xa0909f67a7745300cee6278605e3cb79e5a9564cd6e81ac379b285e0eb6e1849537326b546079d7bf676c8e33a166cad00ab74a396f12c9f4851fb64612f6aeb911db550e0aeae88e1b90831a5a858ae64f9262f67403327d85fcb345df9fca4" - }, - { - "aggregation_bits": "0xffffffffffffffffffffffffffffffffff", - "data": { - "slot": "348240", - "index": "9", - "beacon_block_root": "0x15bd2273ad32344e34f842fc77ad8acb2a2eaedafa6e5328ef799babfe81113d", - "source": { - "epoch": "10881", - "root": "0x12a21e7bb91e09dac76d5d3f170db6358785032f10b9130a1e92e6f4409f2ecf" - }, - "target": { - "epoch": "10882", - "root": "0x1c8a9a3a0d4c9d72a93b9ff2ea442a986f4d6dfde52953e48a146206393e7708" - } - }, - "signature": "0x886d038ddd7598cfda720dfe1caf83e030e24b207bbc0c97d012fbf5accbaa2f63366f32fe643aa1fdf6c8282480cd51165710bb786d77ecfb72ef7cc9d55e342c94fb57f5a75d50a0d486ecdf014bb08e0195f24202911c86efb5b46b2167ab" - } - ], - "deposits": [], - "voluntary_exits": [], - "sync_aggregate": { - "sync_committee_bits": "0xffffffffffffffffffff7edfffffffff7ffffffffffffffffffffffffffff7ffdf7ffffffff7fffffefffffffffffffbfffffffffdffffffffffffffffffffff", - "sync_committee_signature": "0x877de19f5fff89de5af36954d4c7f7f5c2ccf6f8dc39fe7e3eb87c3357fca26f0af747dffd0f992c8844a20763e9f8a51858d0be70ce610055c6421d340160adec0ddcb706a7d7a5c45edff7b5f9b9a039fce093cea41c7a5699834f9de48b94" - }, - "execution_payload_header": { - "parent_hash": "0xa330251430b91a6fb5342f30a1f527dc76499c03a411464235951dbd51b94d9f", - "fee_recipient": "0xf97e180c050e5ab072211ad2c213eb5aee4df134", - "state_root": "0x079f2cc22a29388fd4fc20f451cbaa3ff39845d68b2c368ff7be314617418e38", - "receipts_root": "0xed980a4cf6df8ba330c14ed9fe0597ec20515f44e5a9adfd2f7b72aa14890996", - "logs_bloom": "0x0000000400000008000008000040000000000000000000001000104880000200000004000000400000000204000020002000000000000000000000000022000800000004000000000002000c000000000000000000000100000000000000000000000000000000000000000000000040000000000040000001000014000000010002104000000000000000000000000000000000000000000000000000000080020000000000000000002400000000000001000000000002000200102000000040100002000000000000000000000000000000000000000800000000000000000010000000000000000000000000000000000400002000000000000000200000", - "prev_randao": "0x86cc02ef030b0c147321a7f94158c1b33cb730f8baac3c59955b983fda3ae39b", - "block_number": "330714", - "gas_limit": "30000000", - "gas_used": "369098", - "timestamp": "1679442492", - "extra_data": "0x", - "base_fee_per_gas": "7", - "block_hash": "0x4ab1ced57222819bf6a6b6c1456715011585599a1cef18b060eb364811bbb14e", - "transactions_root": "0x6d47bae3b4963cbde00ec39bbd6442540afe26f8005e73722489904836008bfc", - "withdrawals_root": "0x5dc5f3ff8bade8e1dd04e5cf56292b2a194a2829e1c8e8b4a627d95e08296ba3", - "blob_gas_used": "4438756708366371443", - "excess_blob_gas": "12504111653614393862" - }, - "bls_to_execution_changes": [], - "blob_kzg_commitments": [ - "0x95cc5099bbd8420d8ebade383c00a2346dace60a7604f768cd71501757b4d72eeb7d5474a6b615af10379d69aa9f478f", - "0xae9f2d2217013ef61f995f9074faead9ec24e8048440164ec3d6029b87d43686dd0c97c2df9554fc997d0d66c3a78929" - ] - } - }, - "signature": "0x8c3095fd9d3a18e43ceeb7648281e16bb03044839dffea796432c4e5a1372bef22c11a98a31e0c1c5389b98cc6d45917170a0f1634bcf152d896f360dc599fabba2ec4de77898b5dff080fa1628482bdbad5b37d2e64fea3d8721095186cfe50" -} \ No newline at end of file diff --git a/tests/data/signed_blinded_block_holesky.json b/tests/data/signed_blinded_block_holesky.json index 54bd93ea..f70a69ad 100644 --- a/tests/data/signed_blinded_block_holesky.json +++ b/tests/data/signed_blinded_block_holesky.json @@ -16,1744 +16,11 @@ "attester_slashings": [], "attestations": [ { - "aggregation_bits": "0xfe7fdffffefbffefefffceffd7ffdffefffdfee77bf7ffeffffff7fbfffff9fbfffedff7f5fffffdffdfffbffffbfffffefffffbbfffdfdddffedbff7e7fffffffbffffeebfbffefbfffd7fffeff7fb7ffdfdfff7ffdff7dfdfedffffdffffdbffd3feff7f", - "data": { - "slot": "1714952", - "index": "18", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xb39613b610af1f1b4b1eb09b563b5a03194f3350846981c63c76e1ccc8b56f96425530dcd1305d26b6c9bf873aefd8d209da4552448309d7b748694a0d08b3a5d8ade12012d6f300b0eacf06510313886508afd90cc87ab8a7048e624c7e3001" - }, - { - "aggregation_bits": "0x2ff7ffffef9bbddfffffffffffeffffffbdffbfff7bfeffefffbdffffbfffb7fff3fffdfefff5fbfdbffffee95fffffecdfffdfffffdffffeedfffdffff7ebffffffffffffeff7fffffb6ffff37beffef6ff7fffbfffbfffdfffbbbefffffefe5ffeff7f7f", - "data": { - "slot": "1714952", - "index": "59", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x81f1a92bc317ab2d5e04e8be6aad68849df1c20e27637db5f5ca76c511e02deaca975510530a113a8a4dc5db1b3687ee0a203a3409c2f24c4378cecee339ed6bb5eff03430d41fc9e2fa643f0081e8977f9a029d5906f553f60dee783c156679" - }, - { - "aggregation_bits": "0xbfedecfd7f3ffdfffbeef7efffff7ffff5ffffffbdffffdfefffffbffbfbfdffffffefdefff7ffff7fffeff7dfbefdfffffefdfe7fbdf7e7ffffdfdfeffffff77ffff7ddffbfffd7fbffffdf3fff3efffffffff7fffedbffffef4fffff7ffffffbfdef7f57", - "data": { - "slot": "1714952", - "index": "54", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x92da0aba1f0405de01f6221def360ffb0e472576049673fd13817d64a745ebba13afb9ec0921343fc1a4a2780274495906d6cabda29f9d21fe1e1301517ec28603f8c6b23cafec410c0d3d0ed8a5e3595a073521691865039090b24830ca79e6" - }, - { - "aggregation_bits": "0xffffffdffffffef7bdf7fcffbffffffdffcfffffffefd5dcfbfeeffffd7fdfddffffbfd7fffdef7fbffff9f97fbf59fdffffeeffffffffdfffddfffffdffff77edf7ff3ffffff7de7cdfeffffffffefffffeffeffffff7effdfffebfb7fe7fff7ffffd7df7", - "data": { - "slot": "1714952", - "index": "26", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x922bfda3ed2257712a87a415d5c344c0ed47f48f9f67da3ef15c862f4c9580af91f7738bf422c99b200b69ec9ecede9700adb37e1e0901fb38718bb0a636a585990f738b2227b77c4f493c14a732f293f90ac856b6aa3de05a470f2233745848" - }, - { - "aggregation_bits": "0x0efff7ff7ffdf7ffff7fcffffbffffddfffeff7f2fffbfbffffbfd63fe7ffffdbeffffdafffffff7defdfffdfdffffffdf7ffffef3fffefffffbffbfeffffbf776effaffeb7fffffffffeffffe3fefffffffffff7bfbf6bfeffffffbf7f5ffbf1befeefb5f", - "data": { - "slot": "1714952", - "index": "22", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x84f746bcb4e2521ce50a7cbfb54de74390aafc0811a2d83ebecb20fba694934f32822248cece141a1caa1ff2e241cb7407dfc9891d7e10e4e774d6681b068d23e22c636bc4341effc11c00ef14285d6bec031e8c496ca0e277ca13135c374c12" - }, - { - "aggregation_bits": "0xe7b99edffffff7ffbff7ffff77ffffffdfff7ffffffffbf7f7dfd77cbfffffbbffffefb7efffbfff7ffffdbfbfffffbfff7fffffffdffeefffeffff6bdedf7ffdefedeaf5fbffbfffffffff5fdffbffdeef1feffdfdafeefb7fffffeff7fffffffff4aff5f", - "data": { - "slot": "1714952", - "index": "49", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xb33ccd0115e8e1dad46ac5357aa07a00d5e0c6e0f426e47856d5fed5914d503d085dabbb6c43169796b13d2c85b4335211ea2723e9d3f36ce611d91d33abfeb117168ee7f55982dbba8bda6df3d56ff938e6f468d6ebc68ece27f19d023456a6" - }, - { - "aggregation_bits": "0xffffb7bfffffff9affdfffffaedbfbefdbfffebffdff77f777fff77fdddffffdfbffdfbfffbf4fdfffefdfffff7ffffffffffddfbdbafebfbffcffeffefffefffffffffbf2be4fddff5ffffffffffffd9ff7ffffffbfffaeff7fdff7cdffefffff5dfffff3", - "data": { - "slot": "1714952", - "index": "53", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xb69bb18b6decfb01ca250556e7ba18211feeecd4b3613391d4014041f9626496e74ae85d5103d4142979fcce110ec34e03e7dbddddb164127eb9380eeb1bdbf73a55dd79721a58fa0e440952f9503f5ee1f5b82dcea3d7f5a64a0a536635638a" - }, - { - "aggregation_bits": "0xb7feebffdffaffffdffffff7fb5ffffffffffffbff9efef7dfbffff7bbffddddf7d7b7ffeedffefffff77ffff7fbbffbfffdff3fafdffbdfbbfff6f7fb7bffeebdfefffeb7d5ffffbffffdbffffbfbd7fff79ff6fefffcf7ff7ff6ffffffdffffffffdf7ff", - "data": { - "slot": "1714952", - "index": "4", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xa6fe5732bbcd2b8097b14ee811612497c9852ca0908b3d264d5263a6f4ead411330211954dd0c3d282927cb27f0358580c08da2e7766820c5e2501ffe734e9900800311103aa4c1e59361305e341d3f725066979fbd0f2fb66e26fb87b500ab3" - }, - { - "aggregation_bits": "0xfffb7fbffffff55fbfffeffcd57bfffd3bffeeefbffffefebfd7dd9ffe7fbeefffffffbfffdfffffffefff7efff9fffffffffef3ffffffffff69ff7efffff7ddffeffdfffffff27ebdbffffbbfef7feffbfffffeffbbbf77efffffbfdfbbe7fdeb57f7ffbf", - "data": { - "slot": "1714952", - "index": "11", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x9199fc4b46ec0aa08687f2986f68326a91b23e87894865a6e06381148689fac7f1b1602d7cf974e74625dc5e2490f2db01f8197291e46a53c32fb40c6354db11e9cac6bc811e1888c54feeaf6f297e0320e301c87ffb86948d7edbc20f8f5476" - }, - { - "aggregation_bits": "0xfffedfdfffeffbffebffdfffccffebbf7fffffdfedfdfbbffff3fffdffffdefdbdfffefe7fffe7fdfdff769ffffdfefffffdffffff3fdbcffadff6aebffffbfff7fbfff77ffbfed7ebffbfbffffffff77f7fedf7f77ffbefffffff7fef7f7ffddffff7dc7f", - "data": { - "slot": "1714952", - "index": "25", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xa5e002abb3fea2d13ace94902b954e05f225a26fee358680fb65b351c3aec1a1b29ebd1160c50a663ab09b907dfdb88c03e241dc0e38503b178899677bb0d5ca784e01fcfc94eca47bf3e583c446415dc104c7127141cd17d222d6223cbe454a" - }, - { - "aggregation_bits": "0x7f7f7fffffffdbfff7fe7fdfdfffffff7effdd7fffffffff7b9dfffaeeffeffdfffffbf7bbfbffffbfac9fffbffdeff7efeeffffffffdffd5eeffffffffff7fe5fffbbefebff7fdffbd6bfeafdff7dfdffefff7ffff7fdbffffcffffe7ffcfff7befefea7a", - "data": { - "slot": "1714952", - "index": "35", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x96cac8b1a62e1904226799a84363d619bc35bd1d668a5ff1f6c182497d1a9c2e92aa7212ea4ce69787a0c2af79f6e43205251334cccc99b2cf630a7fc8455361d387a1107abff90f49932141221f7e640cebdb9813142d1e10ef3fdb44ee013e" - }, - { - "aggregation_bits": "0xffffffdfbbff7f7ffffeff77ffffdffffeedf2ffffefbfffffbff7ef5f7f7effbfff2ff7fffffffffffffbfffeffbf7efbfffff3fbfff9ef9efbf4fffbfd7ebffffefbfeffdeffff7ffd9eb7efda6fbdf5fffffed7efddff9ffef7ffffff5ffffdcfbedf6d", - "data": { - "slot": "1714952", - "index": "23", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x8140723f88761f58f9f64284f20262c42dc6734e3a7bcd0dd809dce319451ba736cca8540d327eb0b0997d77536921e50a1269cb52e7267d863d66afecde869ca6b01c6f2cf803dad0dcde72278b1a7d6b80fe56c8a2303a321635c55ca14485" - }, - { - "aggregation_bits": "0xdbfdfe7cfff7ffffdbffffffdfbfffefffffd75fffdd7fffffcdffcf7ffdfffff93edfbf7d9ffffef6fff7fffaeff7fddffef92ffffbfff5fffefefe7bfffff7dfdfefffef5ffbf7f5ff7fdfefdff7fdffeff7eb7f9ffbffffbfffbfffffdbdfbffeffff7c", - "data": { - "slot": "1714952", - "index": "7", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xb1b25fba6b74a62d228b3aaa1b1cbf949c787136cb3782c70d2184f900fdb77eb9582950be14cf3ad2fb85902369df91094cde2936f02a94cc48ad0fcf6c48038c242db150d8776e59ba5c4203f5e47ada9c8bc6c5ebd4ad3983723bc5e11f71" - }, - { - "aggregation_bits": "0x9bff7ffffdfdfeff7fdefffedffffdfffdf7feffefffdffdffbff7ffbf7feedfff4bfefffea7e9f37fffdffffbffff57fdfb7f7fffffcffff7fff7dbbffedffff58fff7fffffbffe7effd9fefffddff7dfff6bffffdfff7ff9f7effff77f7fafdfcff7fff3", - "data": { - "slot": "1714952", - "index": "9", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x80b46b659e5fc00055c58f387b91ebde2322dfe3396301540cf517ca1b319c839013c125a007be8f6b0ffaa8f11b0762094d988a3dbe8dd91e6753eddfbcd1fc23f4fc5b81ac45b76eab733a5969ae96404d83cdbe0b8e6072780b95123023d8" - }, - { - "aggregation_bits": "0xedfffbf7fbbf7feffc7b7caffffe6dfffffeffffffffefff5bbdfeaeff7ffedfffff7efffff997f6fb5ffdef77ff7df73fffbffbfeffbfff3ffffffebfffffbfff77fdf5fdfd7bfbfffd7ebe73dffffdffeffbfffffffeffbfffeeffffffffefcfff7dff7f", - "data": { - "slot": "1714952", - "index": "60", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xb84255394748df58d5282487a1811f509bd5f9540ee4206c3b3b03d6e09a01f8479ad659c656be8ff97828634716aaa419c8b797a81683746c2234e22a5d70b5f9358eb31e178472f7acab55297005b368806887b8c63f60f66506b348abeebd" - }, - { - "aggregation_bits": "0xbeffff6affefbdffdffff9ffff6ffff3fffdffdfdfeffbffefffbdff677f5efff33d7fffdfdfd7ff6ffdf7fdf7ffffffff7ffeefbfffffb9ffbffffffb7dfdff96fbfbffffefbf7ffb7efffdef7bffdbfaffbfbff7ffffea7fefef9fffcfffdffdcffeff7f", - "data": { - "slot": "1714952", - "index": "28", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xb6e3bf1370c024c10e90efec922080bda354b19843078bbccf6c8a87c7994d094302462b6c5aec2a28a0ff555c9b1fc007bacebb0a5b51a05186c259b031e7e842b28f53aaa3d5a38c6ceaee1dcd318f579282397b3c66cdb1304d42aa7f403e" - }, - { - "aggregation_bits": "0xebbf6f97fbfff5b5ffffffbff77fff6fabfba7d7ffffffffdfffffbbfcebfbbfbfffffffefdeffff7fefbefbfffbdfbfffffffffff7f7e3dbfffff77e9ffffeefbff7fffcffffbbfffcff77efdffffcfbb7ffefff7ff9ffe2fcdffffffffffefbffbfe8f7f", - "data": { - "slot": "1714952", - "index": "15", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x96fc5ddbcfdb01ec4da77f117aa0cdb800b83cda2e10dee478afbf2898368d479b0af1f9d5bfe0498d05fb55c7f63ce40da874f4f194fc5d05606a216a49a37f17b15fa4c7316f31686c0ad377db1115a4bee71f96f8c7c8b23ced1f103ba8d7" - }, - { - "aggregation_bits": "0x9fffbdff7fd7f7fffffddffffbf7ebfffffd2ffbfbffbff7fff7f7fcfcffdbffff7df6bffeef6ffdffbfefedd5f6dfebf3fd7ebfdf9fddddfffffeaffff7ffbfffffdff7f7fff7ffdfdfcffff7ffffff7df7efefffffeffffffffe7fcf7effddb77bbfff7f", - "data": { - "slot": "1714952", - "index": "44", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x83a4f5e6b5da3039c319a671bfe5143476efe2fd4c40238e36cdf24bdf8502e6b4a9deffa0fe13495b8a96b6161077de0c801a4daaa9a39c6e9575868c3bd19c1ab56cadc0eb56fbaa9bff2674df2452f58c6b56f1e1efac50a4aeb630ba920e" - }, - { - "aggregation_bits": "0xfff5ffdffbbffffffbfffff9dff6ffffeffaffff7df7cfefffeff3f1df7ffd9dfff5eff7bc7eeef79fffdddfbbfbff7fbdf7fdfffffdf9ff3feff5fffffffbff75fd4ffff7fffffff7fbdfffffffffc7f5ffffffffffd77bffeff7dbf7b6ffffdefff5fffd", - "data": { - "slot": "1714952", - "index": "36", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x8645e9b60625bab0b6d0c957bab93b5c832df22495a4d3b12b545bf016b4300841e8d9679d81804a69b5d7ee56f8cfd41315748a90a303500df90c692d20ec0b47a98bfd9750e71634407a305646d68b07a7ceec4c86839970a8db69e81e3cbd" - }, - { - "aggregation_bits": "0x7ffefff5effefffffff7fffffff7d7bdff6ffdbfefddf5bdfff6fffffbfeefeffff7ef7f79fffffffbfffdfbdffffffdfffffdfefd7dfff7ff1fdffe9feff1f7bffffcffffd77f7fdfdfefdff7cffbb2bbfe77fcffddddfeffffdffeefbff7dff7bee7fd7f", - "data": { - "slot": "1714952", - "index": "17", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xa1bbda53f8492b06a58864dfdf0c8252f4a56ff5e0ca7505872bc77a63584e1de1b424a3b1899c373b0c9394015af4020f2f9b0d9185e5a9a70bd8b8455971c6ddabca3e2e4898b162c12a0f39f47eb94b9d87d67ee0cd0889161ad2e0b7d117" - }, - { - "aggregation_bits": "0xfa9fddffb73ffeffafdfafeddfdffefff3eddfbffbffffdfffe6ffbf57ffdffff6fffffffb7fffbaeb7efbfdbffffae7ebf9fffbfffff6ffffdff7f7ffffbdfffffeffbd9fffff7ffffefffffff7edeabfffff77df7efdffe6afdf4fffff7bffffffffef6e", - "data": { - "slot": "1714952", - "index": "3", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xa4b91c0af66a4809d0e8db72872620b531435783b2de027ece05b2d19dbad0c8829abdfd24275d25fb7803f322d0fee90f84748ba29821cbd14f868ee2df6d0ac4d89ee4f2ba13c8f80298f7bf96fc3aac95c05ece5f3fc053929ba7fe571a4b" - }, - { - "aggregation_bits": "0xeffffefdbffffffff9b7ffbf7bbffbebffb77ff7ffcffffbef07fecfbf7fefffffffeffefffffdffffbfedbfffff9bfeafffff7ffbf7fb7bd3fdfffafdf5f7fe7effffffffcffef7ffefffda3fdffffffdbdd75dbfedfffabfffffcffffafaffdfbffbdd7f", - "data": { - "slot": "1714952", - "index": "47", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xa450a165d486642f2288d51f26f88bf5e1b460857a00a414f13b01ffc7f643f8990f979f21f46289de4402552e33d0fd12c34c36df8449075d67331bddd5bd34200dad67f99c71b3334956752a78b8b942eda195c766c9290bcb331cea3bff3b" - }, - { - "aggregation_bits": "0x7f7fefbff7dffdffff5597ef3ffffefffdf4c7feef7ffffffff7effbcff76ff3fdf7ffdffeffef7ffaff6ffffdffffe67ffbff7efef75bfffff7d3fdcfffffffbebffdbffaeffdffbbdefefb7ffbfffff7fedfdbbfff6fffffffeffddd67ffbffbdfdf7fff", - "data": { - "slot": "1714952", - "index": "56", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x947124f9470014b01ca96284e044ef6a716b332936310bd82f7ba87af294a844b872ceb383d8967e836452b16d1406a00dcdd9413d7aa301492357e3aafa8f95389e4b8a74c11c7926c0d9c172bff0a0a66355e91e7c70169832600e2a337c5c" - }, - { - "aggregation_bits": "0xefffff7bd7eefafedffe2f9fbfbf7fb79feffd6ff7e6ff9eefffbdfffffffdd7dffff9fdffffdffeffeffe7dadfd7ffbffff7dfffdfdf3dffffbff7ffeffdebf7f7ebffffaff7fffffffffffbf24fbabdfcfdffffefffd3fffffefbffb77f7fffff7bffcff", - "data": { - "slot": "1714952", - "index": "41", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x8faacc336f2309c95afbb248bc53570328b2eb772f3ea369717b39ea0161e6dfa13635285447989994ff27dddba648ed02312a7c4c7171f69274b70c57d48cba44ed886a3eda9012e4ba73836ac307655546774ebc35c752bd93f7992661ae5c" - }, - { - "aggregation_bits": "0xfffdffbfef1fbfffdbfefafbbcdf3e7ffffaffbfefeff7f7efffdbbeffffaf77f1dffeffff7ffdaffffffff7ffbfefd7ff7fffff7e6f67fffb7ffbfffffa7bf79fff5f77fff3dfff7fffffddd5fbdfffffd72f7bf6cffdfffffffeffef7dbffbfdffdfff79", - "data": { - "slot": "1714952", - "index": "50", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xaa18dd659ef6f47d671a59ad4f2dde22c212dc808df8eab9b2dcdf5baaeb36ed69f59fcfa9e3965fd9495487ac1415a1046d855bfbcdccff4265549940477a4ec406f2e72a5e2af7dfb5012172dc96249f3743c80ce16c325eb2e9ac61039389" - }, - { - "aggregation_bits": "0xd7ffff7fbdffdfeffdedffeffdbfffbfdf77fdefffffd7fdfff7eddff3e6f7feffbff3ffdffff6cfff7cfdfffff7edf5bffffe8fbb7ff7fffffffffff3ffdffffefb9fdfffbbff7bbe7fbb7feefffdffffdd7fffecf7f7df69efefffdfff7ffef4ef3dbf7f", - "data": { - "slot": "1714952", - "index": "5", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xac0109415af0abcff2f11850b7e91f9a4a1348a31e8cecec64d14ad8350d60148e8d8166572f0d39c3fbb108831d29b60b801a4a347d8b8b5b11873c43aed48447737e905ac2a9571084be1d86040ff3438ae0e96f310fc0c60b746d6402ab65" - }, - { - "aggregation_bits": "0xf6ffdfc7f6fbfffffdffffeefbdfcffbf7fefc7fef9df7dff6bff15fffffdffff9fdfdf671ffcf4df7ff7fffbfffffbfebfffffff7bf5fff6fffffffffbee7fbd7fffffeffbffefe797fffbfef7fffffff7fff7bfff9fdffbffffebefebfbd7d77bfd7fd5f", - "data": { - "slot": "1714952", - "index": "39", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x8293bb7892263821965b733b574dc827f856cac798e0d3c48911eabb324e4612fbedc7821c253e50c7cbd198111d882c04bbc3d3c19899c360921c3f1b94639b59599fb987fa4d9c304ae3e54659b2b1cb5b7d41225189c793fb457fe9a407b5" - }, - { - "aggregation_bits": "0x3fff774f7df7f77bd5efeefffbfadfdef3f6ff7fcfefffabffedff7feffd7ffbcffffeffe5fbfffffbeffddbffffdff6ebfff6fffff97f7fdfffffefc7ffdffebebdefbf3f7bfdbffd7fffef7fe0ffdffeefff7fffefbffffdffeffdfffff7fffffffffd79", - "data": { - "slot": "1714952", - "index": "30", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x8ba7b10bdeb3bd44e14ed65ede0069f60d05980b8a91360564c50b89feef44420eac0cdc1a008f692d0a9223e8dea57205a5e839fd07866526904a25bf130214a2d2c2740676148247692516a1d6f0eb4cedd6d73a9344257d2ae14826824c45" - }, - { - "aggregation_bits": "0xfffffbf6ebffefffdffeffefffd7ffbbfffef977bef7ffeebfbfffefeffffbb7fffff3f7fdfff7fefefff77ffffddef8ef77ffdfafbfffffefff5bbffffffadef3ffffffffdf7efcaffffffaefbfedff3dfeebfffff7f8fa3fffefffe3ffffdfb6f6f77173", - "data": { - "slot": "1714952", - "index": "10", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xb03666c9209e8d0fdbfc87c6363877af4a125ba780106e1cbab2850d522d49c0178a6c7f39edbb2c7e7af7738980a69003b19d3144827e60d8547672f0d7d02ec73dc0845fa1ad443a9f861506e0d1f8a5e9eb4f309fe28a6a0028508520fcb1" - }, - { - "aggregation_bits": "0xf7efffdfdffffbbffffffefaf7fffbff9ffebfffcfffeffbfdf7ff6fe7deddfeffffffff3effffabf7fffbbffffffc8ffecfeff777f5ef7ffffeb76ffbebfb3fbb7fb73fbebffefffdfdfffefff72ffeffaffffdbb7fdffdfffffe6bf3bbefeebfff7d7fff", - "data": { - "slot": "1714952", - "index": "21", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x93b51605da3e5728d5c04263bb17d850d7e4b9cbe7a7eb0a72919c0cff0c2842935f4db5c9d7595e7ae53439e63f89000d554234f3dcfdd72d30d65758398d4f70b7342de7d8685fda2c97aa9ffc69c2a637b8e69b48f48b32cbb4b064b3684c" - }, - { - "aggregation_bits": "0xf7ffad7ff7eebdfffd7beefffffffff7f7f7ffffdffeffffffdefbeffcffeddff77ffb7ad79ffe7ff7ffcfd7ffcffdfeedfbffbffffbff7fffe9fffbfff7fffffffffcd3ffedbd7fafdff3fff3fbff657ebfff7fefffbfaffed1df6ffed7ff9bfbbfdfffff", - "data": { - "slot": "1714952", - "index": "58", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xb24b94c512e9b28cfdf03290224a0d273a530a8893611fd53c26471a25cae5e8d9d361e221c7e8c7e859b1dc5ea859e1099492d95c208728add8025a265e093fe736c032218ae65cfa283fb31593fb99bae5a56faa50e0800b6a53f8bd0d709c" - }, - { - "aggregation_bits": "0xffffffa2ffff7febfffbffbffbd7feffdffed7ffffdf9fefbfffffff3ecaffe7fe6ddfb57ddefbffdffbff0df7bebf7ff3fffefffff7d7dffbffbefefffffefefed93dffdff3dfff57ffedfd7f7fbfffbfffffff5bffbffefffff7faefffff7ffdedf7e6fd", - "data": { - "slot": "1714952", - "index": "38", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x8f01d9502cbeb4597cdce08741bed557584b5aa7d3aa1933c45adea7635e1e41f1d70d135a53d93b0d2b7ddc9a469e4b17bc4d73277ef3f3778581fbcd95de088b2d3d964a1f4481a4f7d341bdefc3d72cd31b4071dc81639b459aa97bc70610" - }, - { - "aggregation_bits": "0xbddfaffcfffeddbefff6ffffefdffe3f7ffef7f7abfbfd5fbffdfffff7f5bfffffeff97bfbfbfbffe7fbfb9ffaffedeffdfafefff7adddfdfffffffff7fbdbbffdff3ffffbffff2febf3ffff7ffffb7fe7ffdfff9ecffebfbfdbfffffbff5fddffef6e7f77", - "data": { - "slot": "1714952", - "index": "27", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x85d41c77912af5f7000fc5f2bafb1d850027c56d6bfd9b749aefe54330794303b1c29a9e9974e929739da490f672f785074dca3b782f65cb31f38f3fe4d5785e9e6a5e84e71b978003fed7ea21ae8224e0a649d14213d024b4316076787e2263" - }, - { - "aggregation_bits": "0xeffcb3ffbf7ffff7df3fcff77ffffdbdfbfffd7bfffdfbbfffef7bf7aefddd9f7a9fbffbffff6fffffffefffff77fefeac7ffc7fffffffbfffff7d7ff7f77fff3fef7dfffd7ff77c1fd8fddf6dffffffdf7ffdefff7fffff7dffbfffeff7df7aedbbffffbe", - "data": { - "slot": "1714952", - "index": "33", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xa37a5e0b2632126b286c2b6776da31415f82749f549e9f1878a6cce0c0c2dd89c67ad2674a0c7dfa0c0883b88804fca507c40d0a454b456706a65b3af3ddf49b96ae6bdc68da3449b654b196fa69f1f9930ef2b0f3f9a158a3ee70de304bf91f" - }, - { - "aggregation_bits": "0xffffbfaecffdef7f77d7eedfff7ffaebafffbffdfffbefbdfdfb5ff7fafbfefff47f7efcefff7fbbffdffffbfffffffffbef7ffdff7ffffa9f7a2ddfdbffbbfbfffffffffbeffffdff7fe7f7bdfbeffffdffbffcbdbfeeffbffdfdfd5effffeff7e7effb4f", - "data": { - "slot": "1714952", - "index": "8", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x8c127458fe5b22df38335307bd61e2b2f838e2d60ab5db3f7cb3c170aff9485d6e8a4358023dfcb7dc16d9e5532a56370e6719e717a8086f4429d78f4591dcd44d5ae889a934c0afaeb9d6f92d19de5f30ceebf0a6afbd5cee0e4f5927b0f430" - }, - { - "aggregation_bits": "0xffff77bfffbfdf7ff5bff7bbeffff5dffffeffffbbdbffeef9ffffefffdffbfffefffbff7fffcf3beffdffbfdf3feeffdf7ffdfffb8ef7f7fb7dffffdff3f7ffbdfffffd3def5ffbffdfbfe9ffedd79ffbfedffffdddff7fecf38f7fbffdfffffabdfbcd7a", - "data": { - "slot": "1714952", - "index": "12", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x99198196e6932d6c72d8131e4489c066d9a2abeb3beae4847b53038b3c678547aaeded06b64c0324169cd85fccac88990c55988a6f1a6bbf5a59753aeaa3982e68bf1118ceb0170fd5048d86a343dbec1c6d04eaf38cd4065706e53237d9a881" - }, - { - "aggregation_bits": "0x5dedf7f7ffedfffdffe7ffffffdeffbfedefdffef7fcffffe7ff6efffefffbdbfffdcd73fdbfbfddbeffe7f7ffdb7ffffefbfdf9ffffffebfffb2e7f6ffff7feb17fd7efff7fafff7fdffaff7d7fff2fb9fbb9dffbfff7efffdfffeff7beffff7ff7fbfb7f", - "data": { - "slot": "1714952", - "index": "42", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xaee8313d4d15ce6bbb4423ae647108eff1d8b7b8b3933aea71d6de9e3c873584acf62b6aa612cf198c4cb420e4e16e1a068fffbf0034faaebffbb9e4ee582012489aa5583b047ef710fa11b8d77f88a7a119873c0fca1b09e2013f8b5170f46d" - }, - { - "aggregation_bits": "0xffffffff7effffbcffffb4dfff7ffff7ffdffefdeff9fb9ffdffffdffeffffbffdfeddfdefffeffafe7ff79bfff9fffffebdfbe6f7ebebbdbfff3f79dfdff37fef7fffff73efff7affffdfffbfbcdff57ff7ef81dffefd7f75fbd7feffffefbfffbffcf7fb", - "data": { - "slot": "1714952", - "index": "16", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xb94c9f7a10bf5b6eb7c23e9cd4cfeea48eab50bf4a88e29390f524faf31b1d2eefc99bc8767bf9cf363234a590c7b5a4069773ca0d682c629e6d657b6110f4cfc6e10a2bda0d579f79b48ef05587b7791e0a738574c2780313abc4f0f76856b6" - }, - { - "aggregation_bits": "0xeef3dfa7ffffffdff7fffff7f7d7bfdfff9ef7ff73dffbebfefb7ff7ffbffbeffffbff5fdbff7efbff7ff7bec7effffffdffbbff77fffff7efeafae77f3ffa9aeeffff5ffbfaeeef5ffbfffffbf7fedbf6ffbeff5e7fdffffffff7fffef7df9fffddaf7f7f", - "data": { - "slot": "1714952", - "index": "13", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x9554441d017e01f77450c0d6ca5146a4345cc24ab0d97f64898e7207b63af11308acb490f8b262462ca02dd000b52c970134769a9508411563bd261fbdcf727b670d9857c99395decf0ce02053bd04531b5133abdb97f920fde3d1215cd2b734" - }, - { - "aggregation_bits": "0xefddffdfd2beffdffff7ffffffeffbffe7eebdffbffd92dffbb77beaffff7ecffffbfbfcfffffffef6def7fbe7fdbffedfffb3bfffeeff75ffdfffffffffbbfbffabffbdebffbefdfffdfffe7effffcfeffbbfedffffbb1bf3d3dffeffff76fef67ffff77f", - "data": { - "slot": "1714952", - "index": "34", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xb2134aaf3dfe11d9e21afc848ca0835e13c4ab37173380a05d9eb1bc336866581a75ddec1fbdcb0b19501882156a29ec021f9424f5d77671fada9ec6a1f392e241a27c9a5d3d68c2d36fd8b601505f56de3f3f34b4933961e5f236db238f6584" - }, - { - "aggregation_bits": "0xfff4f7fffffff3ffffbf7ff7fffffeffee5dffbfffdfb5dfbfbebffdd763fffefbddfdf7fff7f7dffbb7fff7dffe9ffffdbfcaeff6ddffffffefdbefbff7fffbfffeb5ebff7fcffbfffe7f3ccffddff6ff5bfbeffb7bffffff8777fdfdefbffffdff9f97ff", - "data": { - "slot": "1714952", - "index": "14", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xa773204a35623a5fae90714b75474e517a39710c0af29389626cf14dcfe45b260d9e021e07d37253c1e1862bf93ad64205fba6eef3a707ce20aaf489d5d6f474a8e2aa3e628d50de65a083a69c3b9597bc977cee3af42b16ad973fa05691be7d" - }, - { - "aggregation_bits": "0xfffef7fdffffffddfd7fbbff5ffdfa7ef7ffebffffffffef7f7bfff3ff7effff9fbbdfbefdff5ffffff9fd7de7ffb37fffffffdffffffffffc6bcfbfeefedefeeb6ffeffdeffeee5ff3fdd9bffbfef7d9fff3cbbffebffddbeeffffeffefcdff4bffdfefef", - "data": { - "slot": "1714952", - "index": "46", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xb957b8646073f6612170dbae5672b96a9cd2ede181ced678012d8075c56959252dfbf2a0f4e35f853ced2cd5d703bce302c6d34410608321382fc4e1d4179bd836e65db557ac574f2b4af9069dd4f2329d31b86ff769be4eb98e0893266c6db8" - }, - { - "aggregation_bits": "0xffcfdfffffffb77ffffd7f9ff7ff5d7fdf6ef6f7fe7ffefb3db8cbffefd7ffffffdefdbfbbf2ffeed77fffbd7bdbffb7bffdff5ef6ffffffbf7ff7ffeff37af6fff7f7ffefffff97fddfdffffb9fffdffffb7dffb7efbf9fb3d7fdffeffff5fddfffffff5f", - "data": { - "slot": "1714952", - "index": "37", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x9791659f3be1a912e257374c25109ef44ce8d8f9622ace72149b2dcd97b07a39bbca2b84479e287b0e77acdee826c64a0e4e34e471d6ccd57b0ec2cc3735918a843da7ec930bfb583c7cdb8aab57cb9c24bb61eecf00fc8cf705149f9750e69e" - }, - { - "aggregation_bits": "0x69fffbf3bffbfeffffefdffbefb3ff3fff3ae9d5e7ffbf5bedfbfffffb3bffff77d6f4f7fecabfbfbff7edbfd6ffffe77ffffefdffffdffeffffff7fffffff8fb1ffffffffffbab77fd7fffdff7f7f7dfffbe7dfffffdffbb63fefefdfbfffb7ffffffe777", - "data": { - "slot": "1714952", - "index": "45", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x8e4e23909f4cc089ea5a739ccd63ff0209834bbe7513ebf1b013dbbba2bb0fe353368c53bc88bd1a7750a1610524a45e108ab4f0961f41920b753171fc4863670cece6c71249d0c50efd63d7a839f6d6dd4f8775b6424478a1ae8aa7aa985f21" - }, - { - "aggregation_bits": "0xff7dffff7f5efffffffbf4efffdffdfffbfbfffff5d7bfd1b77bf97fef7ffeffedff8eff7fdfbdffdfe7fefd7ffe7fded6fcbfef7fffffb7fe3fffefffcdffbbcbff7ffeffe7fbdefffe9e7efffbfffddafffbbfbaeffdf7cebfebffffffffb9ffbfdf7f7f", - "data": { - "slot": "1714952", - "index": "32", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x86f7b81a386a27bc8f4b4f3e1fb4355e6c1d34d1b6a950943d24e8064fc234d9767e8b4caaec5ca448fa32834f1e5cd208592635d9770155305185ee3181563ea928a922df9583440a4498478cc3ceabc9379a4040021db5d2460bef9ebd065b" - }, - { - "aggregation_bits": "0xfefffddffcf6dfb7fdffeff91ff55ffffffe7f2fffdee77fff2f77b9fffbffeeffefffdfdff3fff5fffdebbdffffebdfffbfd9ffffffbdfffbd7df7ffb7dffffd6ebfdfb7bfe7f7fdef7fb5fffe767ff7f5fff9efffd7dbffefcfbfbfffdf7fff3fffdff7e", - "data": { - "slot": "1714952", - "index": "62", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x8aba2f93981ec2536533abce9936844c41e4abe4fb03ef283a103b22475c6f44aa40a18d9793c983d208489f922d57880db155b961c89d63605e0b921f693b016e066d734b2a9cfb9315e61d9de8fdbc5b306042aa51720ae7a2402df23ca739" - }, - { - "aggregation_bits": "0xcff7b7fef5fbffbffbfff6ffff75f6ffe7fffbdffef7fbffddffe6befeffddbf7ffbd6fd1fffebfbfdb7cfcbeffffef7fdeffe3fffe3ff9ffffeffeff3ffb7bfedfff7fcdff7f6ffffb7feaffffffffcfbf7ffeffbdd7ff5ffbf7f9ff73bfd7dffffdfeb7b", - "data": { - "slot": "1714952", - "index": "57", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x96d4687920f615dc2ac57a30225f90eb49351de3ffcfead706a6cdf492065bb82f69660d0d24ff4cab47e39aa1e67a530c0a727d2a58c34aaabc0e6b73a2123a3d50f2fe413c994eeb28985e2dc45b5946da58c35dad84f797fcc3d1fd66665e" - }, - { - "aggregation_bits": "0x9bffedffffbdf57627fffffaffdddf97fefffffffaedffdf9effffff7fefffbbf7f7ffefdfffbfffffffffff77eff5fdddfffbedfbefebfffdbf7fdf4ddfffecdddfffcffeafdcffdffffffbfdff9bdfb37fdfcbffdfeff4c747fee7ffef7afffdffdfffbd", - "data": { - "slot": "1714952", - "index": "1", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xb7039e04dc17f5ea59ec1a3af3cc778453c04a890c4685dbbbf6d87161ee808a4037b4974dbb48f02070407ebe8aa5fd1314ee1c388f14f8ae4df033becb5dc30d3b722bf0c59a491af6da25193abe8ae58b449efaa976868d947cd1d1a5edd0" - }, - { - "aggregation_bits": "0xfffdfffffff7fffefff9b5ffffffff7fff9b873bff7dee7fbe777ff7fdfbdbfff9ffddfff5fffffdbffdfbdfffbdefff7fbff7fbe2fbf7ebbeffffeeffffaeb17ffffaefe6ffffffbbbbfdfdffddb6ffffef6bffefbefdb73fd3dfdbedf75a7ffdefff77ff", - "data": { - "slot": "1714952", - "index": "29", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xa92b27b4db0598497715f0b3e236cdbd4b9c5dc1908ade73d798b53e792f5e38874691213dfd829ec4f39e942b66080100ff1ac983a8de55ad47a374b9d9da644f8802ed5daffad9c4df1e299aa91f01374efb118f5e1a218711023e10c36eca" - }, - { - "aggregation_bits": "0xfffedf7fffdd8beff9ffe37fbf7ef3ddfbffdfbcdf6e6fdd7ffefff7cfdeffdfff7ffefcffdeff9fffef7fff8f7ffedfeedfadfb72fffbfffdfffbfd9f6fafdffffffff7fdffffedefaf6ffbf9ffffffbffffbfffb7bffffdfdf7cfe7bd6f5fd7ffffdb9f3", - "data": { - "slot": "1714952", - "index": "61", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x94f1b4ca8cb85d79879a8748d97f41ad804c0db195f7b7bbb4fcea394c1bf251cc0ddf9c6ceb2295d7176b0a85d4f8e91737845758a1fbcb3c30381b8a0002e1e74924a6658e08291cc53a3a26ca1af3813487c6e04c43ed930c22e250348edc" - }, - { - "aggregation_bits": "0xfdf9f7e5ffffffff7dfdf7fdbffbd777ff7be5ff9b7effffffae73ecfffffbdbff1fdfffdffbbff3d7ffffbbfdebbffffb9ffbff7fd7bbfffffffff67f37ef7fffeffcadf7ff7fefffdeaeffd3ff7eff6fee77ffffefffedfd7feeefffbffdf9de6d77df7e", - "data": { - "slot": "1714952", - "index": "40", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x8458095fcadb1130365464bc9ed4fdcaf7320c92c36860630578fe649c480274c129461d9845c01567d91d1fcad0cbfe07d98224fd9668a3f618a9aba7bf01a7c67cd3765e15d88bdfdc3ddd33a77d2b03f10dcf6db9cf81b769076b0346c79c" - }, - { - "aggregation_bits": "0xfffea7bfffd7f79fffffb7c5ff7ff77ff7ff9dfeffadfffffbfff7dfbf3d7effb9ebfffd7ffe1fffffbbffefffbfaff7feffef3fdefddfffb7fffdfffffdebeff2fdffffbbefbfd556ffd7bfecf3b5fff7f3fffafff77cfffdf7afffefffffa6dfdef7fe5e", - "data": { - "slot": "1714952", - "index": "0", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xa2b341bd365df241ad5e2fac0223cb06f6e1cf241b44cf2ac807ccc703a8cfac61d867fce86bf82c53dbd3c3db138b0a01af94de7bb0b457925f823e2b5b6463d5b997127e9942c2afce3ddda58e85e128e999c8c28f5b224a14172bd3e8b0aa" - }, - { - "aggregation_bits": "0xdfffdb9f77ff75fff7d7af7dbfbeebf7fdf7dbeffffff7ffffd1befeff9ffffdf5db5dfffff79fb67bff77e7fdf67fbfddf3ffef7e7dffd3cfffd7fdcffaffffbfffff57f1fafefffebffffe47fffff5fbff7fdbdbfdb7dfeffffff7ffbfefffffaffbe7bf", - "data": { - "slot": "1714952", - "index": "6", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x9972475c0adfefa64816aeb9c552db76a463e55b23f0c99112f2b2a5e07028652c64a0960ae39b43cac52933cc7d59fe1184f05266a7f2bdb1a6936c97f8fcade6f91c57951ec6af94f04592477b798df0e65f27bbaee7d95667f5edf8f21715" - }, - { - "aggregation_bits": "0xfff673ffffe8ffdeaf6f7fdffea7ff7fffcdf7ef7c77bd7e7fbedeffeffdffffbffcffbebfbffdfefddffbf7ff7dfffeeeefdbeffdfeeff3ffbefcf7ff7fbaeff6ddfffe3ffdfefaf77ffb3dbffff7f5f7ff9ffffffefbff7ed7ffd1fafef3dbfdffd7fffe", - "data": { - "slot": "1714952", - "index": "19", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x82bc4e8ff51279d94fa0f29239ae89991ad0261eea98473ef7304212683625f261aa4620ad25fec52d1524d49016d6f41414dce3b3046c131a230f962332b150690916a46cc6832174913ecd90a51f39c25b57bf72d9a329d07793453370f0a2" - }, - { - "aggregation_bits": "0x7ffef7befeadafffceffd4dfeedff76fffbffffeefff3fff77bffffdf7fff77bbfbefdb5fffffffe7ffbfd9fff79e7fffefefff7fffffdfffd9ff6f7fe7f7bffffffd83ff9bffafef7fbffaebffafbabfff3bd7eebb9dfdf77ff1fd7ddcfbff7eff7fffd79", - "data": { - "slot": "1714952", - "index": "55", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xaec7f4fa5a4c43fd7e5da13cbcef7f205dc1ab312a2d08ee3144c01379a2c85214f0c6e72a029fea1b380cd42dfd8f120dd7ec5e3dc8c745292a58289457b90527c28896297ee8dadb8c33b4cd2d3eb039049b05e5b147ef9467789f74f3c239" - }, - { - "aggregation_bits": "0xbd3dfbf5fbdb7377cbfa37ffbf7fffb5fff5f676ffffffafff77b7bfadbffffefff4febb6fdf3ffbfaabefddf7dffb7f8fbfefdb7edefcf7fffff7f77fefffffffff77ffff9fffdfbffeef7fffffe9fe97fbefffeff3fff2abfdffff72ffffefffefdfffec", - "data": { - "slot": "1714952", - "index": "63", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xa5e827e42fe2f1245d99509ea756ce74d26124962771c70d36cdaf8eb75153d7bd3c62e1f10a9724f69e566f3a3d87aa08955bec0f397b728e930b62c532af1f741a7a4557889017e0691de1ddd51f8f6207c185caa98f93432c409f774d4548" - }, - { - "aggregation_bits": "0xfd77fbdeec9fefbddfbeffffaff7fffdffbdcfffbd67fbeff77fff7efbffbffff77fefbfddfffffeffbdd57fbbf767ff6fc9ffca3f6dbedffffff267deefefff7bc6df6bfdffff5ffffffe2ff5fff7cffeffff6ef77dedffdfffffddff7f6ceffffdfef77f", - "data": { - "slot": "1714952", - "index": "2", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x9459d789f38d5feccc20ee94be507198a8f25fe3b69a02e564531244eb118490dbcea7ed66481c3c93196d8c189bddad0566cf1507623b6f89421bd742fd974e245e6c6b47f98016b86025ee25f53afc64d526097ff1a37abe6951226d71cd9e" - }, - { - "aggregation_bits": "0xfbffffffdfadf37ffbff7fbdffee377ebaf7fefbfcffdff377db7ef77dbfd47efdff7bd77fffbbfedff3affffdfd4fc9fbdfddf67fefff9f7fffabfb5ff7f7f96fffffdbf7bf9e5fffeffffffdcffff6fff79fffff7e7fedf4ffefebbd7fdfbf3ff7ffff77", - "data": { - "slot": "1714952", - "index": "52", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xa2120f2ff532e6da99670159f7e95fc0a4d0fa2294fb7aba481e7aacf2b542fe6c93d8164bde93315409c41fa450d9180457cad42674ddc60bf8f02989024211d2ada09d80d2baf641690c1fe10efbe29127d99009eba95a060fc1546608acf6" - }, - { - "aggregation_bits": "0xff7ffffffff9fbafff777edffebdffde71fe3fe33ffd2fff6fe5ffbefff7bffedfefffff3f7effc3ffbbfff3cfffeffdffeb7bfbfffdb3fff7f5eeefbbfefcffeff93f3befffbfda67f7de9ffffdf7fdfef7fdefd5efbdfb3fd7fd7bfffddff6ef5ffefd7f", - "data": { - "slot": "1714952", - "index": "20", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xb1dfe799d60322838259b039a43c440571e336e27002bc6609efea02bec97ef31b87d89f4a1eec870df866337154af230ac6a8ee4db8a9cd737afc52c83b7370aa7fd8554ab66e0ec20092c31743308b3d7e6c4b4395b66b6f23192e673dadc1" - }, - { - "aggregation_bits": "0x7ddfb775d7edf4effffffff7fffd57fbfe7cffffffdffdf7a7a7ffff1f7effcee67ffafef7aff5b67feff9377fffff7fbbff6f7ff7befbbffd7fdffffcefffff7f7f9ffbffeff6fdb7b7beffff3cff7fbf95fdefbeb3dfffe6d35e7f77ffe7ffdfffd6fecb", - "data": { - "slot": "1714952", - "index": "51", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xb3be0444a725c136814b15917dc7ddfd3b6c8ad030ac9b1100d58f609b93468a557f70ea59402a33852becbd22beed6c144c0ffdf6d24274a621c5b977f8ab96f85e7f41dee74514a76ee743aff58f03daadd4a7ca0a03fe5f89f59a2c45ad94" - }, - { - "aggregation_bits": "0xfffffbfafddaffbff17fffeef6bffff7f7dbbe3fdfb7eeefefe7fefffffffbfbb5675dfab6fffadafffdfa71fffcffeb3f96fefebedde97fcffffbdfb7dfffdf977f3d7b9f336fefeefffcffdffeaef6fff7efeba6afbdfd3f7fdff7fdfffa7fbfafbd5fdf", - "data": { - "slot": "1714952", - "index": "48", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x8582b5bf5dd71da28d327e863a20a6a8bfb3298c7fe59efed6b5a14fc3cd0667199d531431ee5e408f3a680efbae63ea0f26e1a1712df42204d118d8d08c9c37c55b3f86b3185ad03403a9ac16e05237fb0d6ca7d81a2fd9b4b3fb448c71eb7e" - }, - { - "aggregation_bits": "0xefaeddffabfddf5bfff7befdfcffff5adf3fd3fdeffe7dfdefbffb7ffd9fef3ebddff3f6effdfeffef5f9ffb72337dcfb77ebef5f777e6cffbfb77bf77ffffd3ef7fff3bffb4fed7eff9657fabef6d7ffdfbd6ffeffffff7fbffb9eb3fff8fd9bfffbf7df9", - "data": { - "slot": "1714952", - "index": "43", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x96fe670f5194932732bab7d3b582aba5ad978837c2924095fa762ef49e8da788ef11ebb9f7836b301a05256121e6ed2f07f6ed3f33cac887f8be1cfb709858b061aa3d6abb2e0b511c3e116712a8f00a5881a1fa193a14a687bd437af3c3582f" - }, - { - "aggregation_bits": "0xfefeeb677be7f9d734dff7bffff1d33ffdfb475defabfffeff6fff8fff3ffeff7ceffffedf57e76c736bfefdfcffff9ffbbffd5e8bff1eefdffffc7e77bf683ffef73bffdfeffdfcffdcd0fb5ddfefefe6ffbdbf6ffe9eed7e357f6ffa7757df69ec9fbff9", - "data": { - "slot": "1714952", - "index": "31", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xafc07082806fbd15244d6b027335046e25f93073022dd1e2025fa0eafadd3e8bd2a452af91795b490e806698ebb14c520bfc92385fc46dc8cec52dce3e3297f48cbd538bc4ba255d41bc8a2650965405e64b9d33cb7fe64b350f1432d149d85e" - }, - { - "aggregation_bits": "0xeb1f3efff5d2fdbcf3dd3cb7dbf3f9fe6ffefaf545fff7f25ffa871fefd56eb7fb7dd7dec2d87ff9fbef73edfca9feb97778bdebeefef57a7bbfffff536b7e6d7b7fabf671ffdf5ffdbff37eafdc7fef7fdf7bfdff3ff9ebbf7ffdc9cc5c655ffeeffcf6ff", - "data": { - "slot": "1714952", - "index": "24", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xa7e1ae698a7f87dd40b9e77a14607bf89862ed03cfd1c3e98eea8cc7ab5f2c01a5f6b6ffe9663d3d85c7294d945dc6880a0b46f84c53e5ab69cc7ea3bdfec570a004add714809c44e34f48debd855b01cd71931b7b85668e42767a57698424cf" - }, - { - "aggregation_bits": "0x0000044010000040000000000000000180000208000640018044000000000040002000080006100000400400001000400800000010800004000000890004800200080000000002000200000040600200000000000000020000000000000000000408080081", - "data": { - "slot": "1714952", - "index": "24", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xa877c562622410e1ae1c8551169ad3a464b4f7000bc4b29ab4d6ca229c8b77601e1175e76b8a301b9e655624c12c52e4036d2f0ad1a6d0d6cf408605febbb365b8066b030506608905d0803f213de40ec55472b4e6bc12235372513d61fe193b" - }, - { - "aggregation_bits": "0x008000000210000280000a0140081800000008008108008010000004100111002010000000000010080c8085214100002014000000800011001100400000008041000022080002810007000000008000000040004000380042102008481000000000200080", - "data": { - "slot": "1714952", - "index": "31", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xaf626cd5f5975f5420af4c20341c423368ea91ba8be211c16c357350fa2fee295c32c1ba041e5ebd258a4e09b82af96102e53fdc5494557333ef3cd772fd8b1878202b7e17065e593468b11b293356df98a7286d0de5500693232c57f23dc1f0" - }, - { - "aggregation_bits": "0x024808809108808000000000002a000000000080020000240010440048000000000030a000020104000000820c0001000001100000002004008a2900000008000100140000000022000008124040000200090000094000a000040000010200011002000080", - "data": { - "slot": "1714952", - "index": "43", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xa94e3b68f90addd35c01e28cbc1b94fae17ff0d7c109feb1d474604a1db60ab9751b3cdf152a16aef8e47f8b25e2db8d00260b25b98377526a2de2691a8ae18195e53401f5c03798ec034745879cee41221cd457bbdd1a40b10d5c83b019bd68" - }, - { - "aggregation_bits": "0xddff7bfb7bfffffdffff7fe3fffffdfbeebfaffffffffffff77dfffbfff7bfff5bb7fffffffffeefbeffbff77f56fffdbffdfefdfff7fbffda7bffefffedfffff3ffffffbfffffbbfffff7f7dfffffd9ffffdffcff7fdeffeffffdfffbffebfbf7efbffe5f", - "data": { - "slot": "1714951", - "index": "34", - "beacon_block_root": "0x62f336d210f91f20d635cea67d71db0da50b89337bf4aa8d1b42b2365afa56ad", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x9572e6e85a8d5c592f490039785a0a33b35962e38d3594a7f7f74c1b1c94cd31200ed48396d05f042216bd67e13a46cb016519b886431377beb98b0676b1cd9affbfad7b08101bd3cebcb0aff187619733afb327e5c7b3256b9fd467b916697a" - }, - { - "aggregation_bits": "0xdb1e3edbf5527cbcb3dd3cb7daf3f9eeeffedaf545fff7f25bea043fefd06e97fb6dc7dec6d57ebdfbed73adfce9feb17778bdebe6faf17b7bbe7fff526b7e6d7b7f2bf679dfdf5fffbf7b76afde3eef63df7bedff3ffda9beeffdc9cc0c654dfeeffcf2c7", - "data": { - "slot": "1714952", - "index": "24", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x981d838e0927891103c6c3de8a4a298bf78bce68524bf6e7cfbe23d2b33e1a403a1b32d90fd9a3b866456059178fedd20b3b3b89738931abb3233cb6472427ba1807a0011d61e31c61f86720fe77d6b1fecb2531bcac9b31aa5ec3a438692af1" - }, - { - "aggregation_bits": "0xffffff7bfff9dfbd9feffffff6fd7ffdbffeffdde77f7ffecf7f9fabffeb36ffffde7bddfffffffbfbbdf5fffff9e6fbfefffbbef7ecfff7f3fffff71fffdffffbfbfefff2bffddfffeffbfffdffffffffffdfffeffeccffa6fffebf747fffff7fefbfef7b", - "data": { - "slot": "1714951", - "index": "57", - "beacon_block_root": "0x62f336d210f91f20d635cea67d71db0da50b89337bf4aa8d1b42b2365afa56ad", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xb3b811afb6b19887125a7599dafea6a933ffb485eb4cefb8e3c6ebf84c207e42b376104c99c1b886c650e40a2a96cbbc0d8bf49c947c5c30aa78c99e571f3bead926341ed2d39deb1c8a8fb33ec2f82f6ab43b686ddb8b91ef1d82dea7432bf0" - }, - { - "aggregation_bits": "0xcdcfdbff7fffa57fffdd379ff5ff7d7f4b6ed677fe7f7efb3db8cb6bcf57cfcffbd2dfdf33f0ffeee77fffbddb5bebb6bbddef5ef6ffdfbfbf7bc7ffeaf37ad7fff7f5ffcd7d6f9fed4fdfffdb9f7ffffff97dffb7efbddeb317fdffef7ff4fddf9ffefe57", - "data": { - "slot": "1714952", - "index": "37", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xa2c9f1c1bc95e81d9d86ae6b03b845db59278a2c0b60af0550426e596159a9c667e2f618fd460d997a1ffb827ab2c73518ce237fad853461ee00f57d524f52ad875d72e45af9c3ef5af54ea9067c43be85a4396d1788804dd93eecb5280d101b" - }, - { - "aggregation_bits": "0xfb7fffffefefbffffff7fcffffffffffbbfdfffbefdfefffcfdfff6fffdffdfff77f7ffffff4fffbe476bffe7fffffefbfffbf7ffffeffeffedcdbf9bfffdbafdffbffff3ffbfefffe7fdeffff7fff7ffffffffb6dfceeffff77dffbf7ffdffffffefdfbef", - "data": { - "slot": "1714951", - "index": "58", - "beacon_block_root": "0x62f336d210f91f20d635cea67d71db0da50b89337bf4aa8d1b42b2365afa56ad", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x95062d30eb177a754abe1e6662d6cc08be5d0a163aeec083edc0540d83c7588670dc6e992d7c622a49936b0a7a09811d0fc840248a9a60d321df9c4ac63205e46527cd21e5bdfb246c559ba52dc70eb00f7c0b9401d309084e9fd1098755b35d" - }, - { - "aggregation_bits": "0x7549feffdff7fa7f35fe7e7ffffdb6b8ff7feeb3fecfaffdefd4de7dfef7ffc2dbfdeadb67f9ee177f9f89df7d5afedff6ef9f77ed4ded7ef6dffcfacb7733bff33ebebefbf5dfdffaf33dd7d7bbf90fb753fafffec3fff3b98b9fb75fbf7df7fafff9727e", - "data": { - "slot": "1714951", - "index": "45", - "beacon_block_root": "0x62f336d210f91f20d635cea67d71db0da50b89337bf4aa8d1b42b2365afa56ad", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x8b8b949de75417bf8cca2f4159a28d9f4bcaf732d8707c1b25f2716de0a58919a79739fa000c40fd76b71f7fb71bf419082f2b1b838153cc528fa64f65138fd014d087978c6311a395e5f27642e6144e77cf6b7b4f810fc3b86d09fb603a790e" - }, - { - "aggregation_bits": "0xfb5ffbdffd7fb9feffeffffefffbffefdeffdfaffffffeffffffff77dbd4ffffbffffbdfdeffe7ffebbbff9fbdfbffeedf7fbffefd1dbf7ff3ffb7ff7bffebfdffdff3efffefbcdfedfff7bdeebff7ffffffffdfffefff7f7effffbdff5bff7f1fe7f7ff7f", - "data": { - "slot": "1714951", - "index": "14", - "beacon_block_root": "0x62f336d210f91f20d635cea67d71db0da50b89337bf4aa8d1b42b2365afa56ad", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x876c7c3e0d762bd9c995ab7bc9825c5f0c790c06651154145091f89cef0d093c66e6d5961c33ec79ca1f3ffdc7ce0e51102fb8519c4f92d875ecffbb974ff3756aaa672d8ddd077c9650ea15335bc7402034b9792508a17d05902bb7089fea6c" - }, - { - "aggregation_bits": "0x5dedf7f7ffeddf7dfee7ffffffdeffafe7efdffef7fcffffe7ffeafffef7ebdbfffddd73fdbfbfd5bef7a7d7fedb7ffffefbedf9ffffe7ebfffb2e7f6fdff7feb17ed7fbff6fafff77fbfafffd7fff2fb9fbb9fffbfff7efffdfbfcf77fe7ffb7fd7fbfb7f", - "data": { - "slot": "1714952", - "index": "42", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xa5291d710fb95fdada52027264361657a2b7d7e08d3517e5a9fef0296113434af3553f17c05b8d96ffd80a0bb0584d020edb7945d5e05fe03746085b2b4bb157d754b8c71056173b1f197d3f46aa27d205ff4a6382edb8211f5b5b2a9896d3d7" - }, - { - "aggregation_bits": "0x000801821c100008088000821100024002400006804100000c8000000404b6228000008008000200000000400000000000000000000900a0040200804060028488000002100080000010000100000000080200002040084000000420000800000002000080", - "data": { - "slot": "1714952", - "index": "56", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x8707d4965ce9e9d01dfb60f181575734639ad64f1971cee60574779e64dd83926c62b12cdcd7d98a5c9b03e51f0de8fb126645bbb5f1add066d0228240725181d04868e60d5d073d9332e39ed80e054ca205f98213041d4f8ba976012633a6ec" - }, - { - "aggregation_bits": "0xdfeffeddffffffef99dfdf3fdffbffffe3fff7fddfffffbfdffffeffe7ffaffffffdf7ffdfffbfff7fff7bbfb7fffffebffffbfbbffedbddfeffffefafbffefffdfffffd7dbf7fffffbfff9ffffffffffff777d7beff679f667ffdffffbdfbe3fffdebfbef", - "data": { - "slot": "1714951", - "index": "4", - "beacon_block_root": "0x62f336d210f91f20d635cea67d71db0da50b89337bf4aa8d1b42b2365afa56ad", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x9106099922691537954bea3f30726176d8d82c083a4a0a085475efef08b1ac33a73fc92bb18ad28a8e7fd75746c6dc3217739cbea218250423e04bf2b0d8b8c8c3be5fc6f614ae34ff4f156ac9017d811b3e2f1ac92be2bad31b1827c190b891" - }, - { - "aggregation_bits": "0x6fefffffbffffffff7f7fffff7bb9fffffeffdffdfffefdbfbdff5fbbfffffffdffffff7fffffffb3ffffff77ffffefffffdffdffffff7bbffffdf7ff9effffdffdfffbffefff777fffffffffff7fbdffffffebf77ffddff7f9ffffbfebfecd7ffeffffffb", - "data": { - "slot": "1714951", - "index": "28", - "beacon_block_root": "0x62f336d210f91f20d635cea67d71db0da50b89337bf4aa8d1b42b2365afa56ad", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xb0d2ca47608c85d39f4bfbdbf9283ff42a1a1a18bad4757883bcec88af31d4f6d99bc8e6d0a27a48f93fb2abfa45dfce19bf35da657502c5cad945f07b22d87234d859185ab2749071008d9ead6e2917b8726c9a3086a689483d1226cda30ff2" - }, - { - "aggregation_bits": "0xfff7bffbeeaffffffdffdffedffffffffbffdffffefff5dddbffdffea7fffbfff5feefdffffff3ffe5ff7dffffff7fffefd3edffbaffffcfdfffddf7cfbfffdf9ff7effb7f71cffbcb7bfffdfdffef5feef7ffffbf777bbffffaffefdafffbffffffefffff", - "data": { - "slot": "1714951", - "index": "6", - "beacon_block_root": "0x62f336d210f91f20d635cea67d71db0da50b89337bf4aa8d1b42b2365afa56ad", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xb0b65d6b508993a928bf37a86e918e0790071503e86ea850731cfff835d25f2ce13d559c541484e7c5ffce3222e2115c195082abdbc5c7ac1f9c1edeca7c30fffa402cb9978cc8433ab99db4b5469166950ab3c7d6816a619e9c73e08884a22b" - }, - { - "aggregation_bits": "0xeff7fffbfffefffffbfab7fadefbfeeffffefbfeffbffffffff7f7ffdfcfbf7f3dbffbfffbffaf7ef7ffff3fffffaffff7bfddffbffffcfefbfff7ff7bfff7fff7ff7aff7ff7ff79efffff7f5fff3bdbfffefffcfbffeeffffff3d7f7fffffdfffd7fd5e5f", - "data": { - "slot": "1714951", - "index": "56", - "beacon_block_root": "0x62f336d210f91f20d635cea67d71db0da50b89337bf4aa8d1b42b2365afa56ad", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xb2356631ad9af8711d33bc9df48ce824feb640240f8b314d2ca9def1f8a00c65d58f3aaf9e2408f6b35c65cb3cfe9923069ac225cfc8983c0113084879cfacdfbc57c614cda96e9506b2e01015bbb3e07dbf46db993c3dc0878e12f5078bfbdb" - }, - { - "aggregation_bits": "0xc7f6b7fcf5eaf3bffffff6dfff75b6ffe7fffbf7fe7ffbbeddefa6befeefddbf7ffbd6fc17ff6bfb6db7cdcb6f7ffef3b9e3fe7ffea3fb9ffffef7eff37ff7bff5fff7fcdff7fefff7b77eaeffffbfbcfbb6ffeffbdd77f5ffbf7f9fe73b7d7d7fffcbeb7a", - "data": { - "slot": "1714952", - "index": "57", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x97a4dbf4b6d6c0e4d61ae7df9ab4b0f6a4a3f9673350cca55689a9e8bb83315101ddd99a904bffaa649a4e44513b06ee010361c217116249b7e5ca0759f67f8448bf7206f28a8bc70bacf68afd3d1dc6aab255ed0d9738a27b614b41936367a2" - }, - { - "aggregation_bits": "0xb83d7841df8a3175436a29e20537b330d2706646653bf30d2d63031dcd19920e90708e9105c327c98a1b2150b1cfb26f9c5fce53389439b178bc76a277cd893ebf66766ac71dcfcc3f78ef0ef6caa13c91bac92aecf396d0892d95e05279298f75af146f8c", - "data": { - "slot": "1714952", - "index": "63", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xa8fe25a935d12bd856d49d56f32e66b156b11b54d561e691f82d93c4f084bc19c799052a5c5b4d273daa7f4f20da6dd3142af80748cfdc5ca3f39a8dd1ac5e7a89b4b01789ed477ef21f4e069e710a1a79b8740af617f9a7b285ab0770013efd" - }, - { - "aggregation_bits": "0x0200000000100000000200000000000000820000008010000000000040480000080000008000000000000000000000002000000080200808000203002800004000000100840000080000000000000000000001800008010000800000000001800000200081", - "data": { - "slot": "1714952", - "index": "48", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xad74f75b71a8659301cb72b2b0e4999f3ebd95e6dde7921eada06c8fe6b6f080e2a30df8afad3a582c3bebee5a1195d614021c171f2dd097b7718e980760bc1d94bfd5143e32f16453f2344dee3164c3c174eaf8c86c11529f9d8da8d30e2d7f" - }, - { - "aggregation_bits": "0xcb063edb71504c9c93dd3cb3fa71e9686fd6daf445aff7921bea0616cfd77697fb6dc7dec2d07ad9fbec632cfca9de11e348b969eefef07a68beefbd566b366d733a29fa30d7db5ffc3f3276afd43aaf62d77bedd71f7188beef7d48cc0c654ddc6ff8b2a7", - "data": { - "slot": "1714952", - "index": "24", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xa5fefdbda9dc2b18cdf5eac82ce2275bba1549560775c47adfdd76fe129f45af3e3735127f100bac4cb67ec15b06e4c10c68a5f139bd3d0606fd00c27b2b50240f56fc172e6faf94c1f95a2e7437288006c02fc03b46aef57d6f14e8e257ddd5" - }, - { - "aggregation_bits": "0xf7fd7fffffbffffefb7ffffff9fd9fffefffccfeedeffeddffff9fffbfffef2fff7ffb7ff87ffdcfff9df9fbf34d7ccfbfdefffff9ff7feae3befffff77fffeff7b7ffffffef7f7b7bffeeb3efe7eefbfe7fefbfbb7ff79dffefbffb7fefffbfdfffc3ffff", - "data": { - "slot": "1714950", - "index": "33", - "beacon_block_root": "0xbc203784e0c6ac176ece769ac76b713c3cc536735f9870a1537a978a71ffd437", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xa4633615ce0f9487d14f03354655933905d5983f7f3b80f35dd1209272bbb83978d54e71572a0d58cde53f624bbb67f413972951e62524cbb93d0de2163d64f397d567a2b6c840c0c4264f86cb44a969352f27eb493a22922d82779abcb175a1" - }, - { - "aggregation_bits": "0xbfffffff7fff7f7f7eeefff7efdfeefffffefdffefffff7fe7d7dfffffffbffffff7fb7ed7feff7eedffdffff7bffffffffaffdbfefffb3fff5fbf5ffb7fddfbbefdf7fff7df1fbafffffbffeffffbff7ffef7bcffb7d76ff7ffffee7b77ffffefff7eff7f", - "data": { - "slot": "1714951", - "index": "19", - "beacon_block_root": "0x62f336d210f91f20d635cea67d71db0da50b89337bf4aa8d1b42b2365afa56ad", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xb3dc3cb43af7d93bb6499055ce3d96fb49724cee629e3a4a53cbf28c21090a847f2ef5f5ee2ee5b82d50bebfeb1c298012e9d9044316982df303010b6ad5808d60298c971caf62158b8cf2683f26446380e81a1118d710940b324ebc56c0dc16" - }, - { - "aggregation_bits": "0xf377ffbffff7f7fbbdffffffd7dffbffbfffffcffb5bfff68efb5dfbfffef3f7ffffffff6fff7fbffffffeffbfff477bfdff5fdfffffff6ffdfffbeff7df7dfc7fffffb6ff7fffbff7ffdffddbe3ffffafeffbf7fdffffe5ffdffddfd7dffeeffaffffefed", - "data": { - "slot": "1714951", - "index": "23", - "beacon_block_root": "0x62f336d210f91f20d635cea67d71db0da50b89337bf4aa8d1b42b2365afa56ad", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xa0f6c8451e4ccc920a4c85dba898aa4fe80778e815a00722cca8b2505d2034b74cde03fc3b0b189363f9098f19bb2a080c174ab64e2d908614c50bad0389c2f0553097c81516ec52f31c2c87281abec8265d7396a62999fd631a52a008520ec9" - }, - { - "aggregation_bits": "0xffffffffbff7f7ff6fe7dbfffddbbffffffffffffcffff5fffffebfbffbfdffdffdd7ffffff5fd69bf7f3fffeffffcff9f9fffbfffbffefff7faffffefdfdbfb9ddfbffdfff3fdef7dfff7ff7f7fedff3ffffff6ffbdffffedaffffffdfdfd3b7ff9fde77f", - "data": { - "slot": "1714951", - "index": "30", - "beacon_block_root": "0x62f336d210f91f20d635cea67d71db0da50b89337bf4aa8d1b42b2365afa56ad", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x95eaf9758d8876ca73c8b0e6604c4e7371680bad8bff23b9703ae433f1f3cd9b0c84350e1f531889244f490e634857ed1800e8352ef9c6060a69b52f93312c231ef9dbc6a95c5788c76793d667a37ba260cbbd0be65facefa3017e1e6f7c4e82" - }, - { - "aggregation_bits": "0x080000020110008000400028000000000012010000000200030000208000004040001080860100000002000c0000a004000084100001200081000000000203840000000810000000020000400080100000000100000082001c0001800820000000a0400040", - "data": { - "slot": "1714952", - "index": "30", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xaefc2951a0d1b04738be7aef7a6c7d8107b8eace7d9d3280a38241867076390442893f9a4cb904ac4fad0751244552d406bc6832d5d5d85632f3f0dd85fdccaf89bfd3c3b7f4c203ec3bbc1c50da801b88c068936189fcfb3a83e82230160bef" - }, - { - "aggregation_bits": "0x0001000000000000000000000000000000000400000000004000400200000000000000000000801000400000000000002080000000000000000000000000000000000000400000000004000000008000000000000000000800000000000410000000000080", - "data": { - "slot": "1714952", - "index": "11", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xafb362b22358ca408558f4e3dfff89c01f812338e391b6460885a6a2c256b8c8826841929f3da0b5f963ef2d6842d4590001648fdb746448d421d04f325d73427b5aa6a4ef045bc22f016a305fd5ccd01220c60bf97fdd308647d538c2b89d31" - }, - { - "aggregation_bits": "0xeefffbfff7ddf7f6ff3fffcffeef2fbefbdfbe7bffcff7bfeeeff23fffcfffdfb7efb7dfffdfffeffdffef33ff9fbf6fdfbfffeef7faffefffedffffff97f7f7bfeffcfaf7deffff7dfef7ffcfcdfbdbf9aff9feffb3eeddffffffdbfeefedf7ffffffdf7f", - "data": { - "slot": "1714951", - "index": "7", - "beacon_block_root": "0x62f336d210f91f20d635cea67d71db0da50b89337bf4aa8d1b42b2365afa56ad", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xb68c391266159614f50b222acdab58549145705fdc5c488aa06c0c71c4cc31337230a5e5c06332a29021e133b540ac610649fb2c80c956a7a75679c646d4adf4639753ab09d61ecb384c7252c46437b93b1aeb6ab1ed876e7e913e21fca961e0" - }, - { - "aggregation_bits": "0xcb063edb71504dbc93dd3eb3fa71e9686fc6dad445aff69a5fea0616cfd17697fb6dd7cec6d07ed97bec632cfca9de916348b96beefaf07a68beefbd5a6b3e6d733a2bf230d7db5ffc3f32768fd43aef62d77befd73ff188beeffd48cc0c654ddc6ff8b2ef", - "data": { - "slot": "1714952", - "index": "24", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x92239710dea4da1e66ad0717d102ff37645bbd8be3ac5b4d339656f00affd53d7b19693fb4dad5405029d9c13ca50e4900edae92c2d52f326c58208e7655b7ad39df0af950548d042b397c3a63151d1a9101781cec78adeacdfdc91bf7459490" - }, - { - "aggregation_bits": "0x422e88380e8c21a4b893656f1452d20169e70c1cdf0a28c16424c7e00e904c8839556420100e080091c0607d0b30ec8241de81d92086c822a529a8ed0f2d81098b30258255f57905288d43cbf84dcc24bb0ec947b3323c6a459a10627bd7313457941ca0d1", - "data": { - "slot": "1714952", - "index": "61", - "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xa5191e9a8ec98d012477f26544027d798253420d84faac3c96f14be2a7b1931e721605ebb2663920fa757cbe8bc66fa11311ff956339b1f1a1a40fc548d29967e614fda16f1a70b36d87ba79409b7bedc695abb1cc9f64348f4b7c18adeeb573" - }, - { - "aggregation_bits": "0x0020000000000000000000000000400000000000000000000000000000000000000000000000000000800000000000800000000000000000000000000000000000000400000000000000000000000000000000008000000000000000000100000000000080", - "data": { - "slot": "1714942", - "index": "55", - "beacon_block_root": "0x3a9c4f6148dbba056148712b09c37f5ae576ad6939c5dbdadf281f736d853812", - "source": { - "epoch": "53590", - "root": "0xcce86f29711f2a67412fff3369189a68fb0f048d746bc9c254f32d6e3f92d573" - }, - "target": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - } - }, - "signature": "0x995f1b6098a9f265dd98eb0f6722a3319015a490109319531c5e6b02e2744ecb5e2f3b9932167fb2f33a406f306421fa0d2429c7a3022f81edcc35f2286f791818e8d6f38aee7a452013e353cfb7e8fd375a08bbc023b003b056d4d6cd77c3c1" - }, - { - "aggregation_bits": "0x0000000004080000000000000000000000000000000020000000000002000000400000000000000000000001000010000002010000000000000800000000000000000000000000000000200000000010000000400000000000002000000000004000000080", - "data": { - "slot": "1714922", - "index": "45", - "beacon_block_root": "0x5d53245b0406d686edc3440bee52fd76f0686e342b23892b1fece1dded9842c2", - "source": { - "epoch": "53590", - "root": "0xcce86f29711f2a67412fff3369189a68fb0f048d746bc9c254f32d6e3f92d573" - }, - "target": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - } - }, - "signature": "0xb7fda78a99b24ba21f3d3cf96493e91991073e96e96101e7b630355c4e0217140a7dde9b79759caa6f3d6e598e57a1c10d1172172a3f10ae6488b9d1f43a510cd2f8a46dbf07ea311b55757e0fb8962fe75d8298424e59025e142b5284ca231a" - }, - { - "aggregation_bits": "0xfffbfffffffffefbff59fffcffbffdfb5bfffef7d6fffffff7f7fbfddf7ee7fffffbe7fff73bffb57fbffbbd7ff7fbffefffcfffffffffffffbffefcfb7feefdff7ffffefefffff7dfeceeff9fffffffeadffbfbffffffffffffffcffef7fffffffdfaff7f", - "data": { - "slot": "1714923", - "index": "28", - "beacon_block_root": "0x97cac9c5541bb9f3e4efa207a6e552f3c801bba14455ee2eda89bef98d120ff8", - "source": { - "epoch": "53590", - "root": "0xcce86f29711f2a67412fff3369189a68fb0f048d746bc9c254f32d6e3f92d573" - }, - "target": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - } - }, - "signature": "0x941b7957e941663fa4a40850814803cdc510f7c3c52e37d297c1690014b8dc24bc8b4baf51000e8bf3fda451252d6a6e06391807d17b7c03110c3765a7f7e5a057b07cb40b940784f413b8b53fc882da16920580f70a9a4f606b377ec8ed29ff" - }, - { - "aggregation_bits": "0x0000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000001008080400100000000000000000000000000000000000000000000020000000080", - "data": { - "slot": "1714942", - "index": "38", - "beacon_block_root": "0x3a9c4f6148dbba056148712b09c37f5ae576ad6939c5dbdadf281f736d853812", - "source": { - "epoch": "53590", - "root": "0xcce86f29711f2a67412fff3369189a68fb0f048d746bc9c254f32d6e3f92d573" - }, - "target": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - } - }, - "signature": "0xa67695e575cbcae7858787ec3ae6925c52d4ad9007e8fc4525d6b14295dcbd49c1fac8324f6a6a6c10692c32c8f7d8ae03fd621381ed7fc9547c959b6b747e60bead1cf7e089964a1f47000014760592f3e753cebe3bccd63e8431ffe1546367" - }, - { - "aggregation_bits": "0x42400000000120000000000400000200000040000022000084a000080048001120400000000000040400000080422080020200000000200000003044020420002002c000000140000008000000000006019000000000008100000000008102000000000041", - "data": { - "slot": "1714924", - "index": "48", - "beacon_block_root": "0x0b8d0eb19686541d8d057f2aaaf3a38f612bd17fbd6eab135e1e855ea9b8aae7", - "source": { - "epoch": "53590", - "root": "0xcce86f29711f2a67412fff3369189a68fb0f048d746bc9c254f32d6e3f92d573" - }, - "target": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - } - }, - "signature": "0x8fd2a08683b5def7aa3d2033a78db9127f4440194f312cdb1bcfba8b2aca9ba30992a236808c8fd62c0926bfdacc54cc0f02d1eb8c1fd8f13c4c50c976621c2cf484fc7b0912c934f7e9ea8c0b39131f026bc8e310aecf3c590024311d6c79dd" - }, - { - "aggregation_bits": "0xbfffaffffd5f7fff7df5b9ffffffffffdbef7fddf7fffdffbfffffffffffcdfffbffffefff7fbffffbffffafffff7ff9fff9eff9fbfdfffffcffcfffefffe7ff7dff7fdfe77bf6d76edfffffffbfff5f9f7b6effffdfdfbffffffffeff9ffdfb7ff7fffd7a", - "data": { - "slot": "1714921", - "index": "8", - "beacon_block_root": "0x3dc310363e81e57d26686d794315ba5f60411cc2ea0e79944c408b9b2b14613d", - "source": { - "epoch": "53590", - "root": "0xcce86f29711f2a67412fff3369189a68fb0f048d746bc9c254f32d6e3f92d573" - }, - "target": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - } - }, - "signature": "0x86a11d3c2569d3902b630754ee126454fa839ed2ba74e0f522548e9ba1e27fc4e725c81a23129898e836d29ccea3dee313a0c2976f569d4d4919afc6a4d699d784c45bd9ec1359ac3fd291c7f03694820381069ae63ccf1f0333f4296f729880" - }, - { - "aggregation_bits": "0x0000001100000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000100000000000000000000000000000000400000000000040000000000040", - "data": { - "slot": "1714942", - "index": "49", - "beacon_block_root": "0x3a9c4f6148dbba056148712b09c37f5ae576ad6939c5dbdadf281f736d853812", - "source": { - "epoch": "53590", - "root": "0xcce86f29711f2a67412fff3369189a68fb0f048d746bc9c254f32d6e3f92d573" - }, - "target": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - } - }, - "signature": "0xb602975df2d30fb3bb285f31a723d57fae57e41fa60308b47ed9407d937bab932c24a9e5db1bea9f83358b582cd00c680c8b14fbfa103ad77d23ceafd3b877dee38c9434e2febf4ca8bfd468333aba8575ea38639027735ef984f94e46084070" - }, - { - "aggregation_bits": "0x0200000000000000088000000000000000000000000840000000000000000000000000000000020000000000000001000002000000000000008200000000000000000000000020100800020000000000400000004000000000000200000000000000000040", - "data": { - "slot": "1714941", - "index": "56", - "beacon_block_root": "0x213723fcbb6e546fae0cc28c3ec03eaaa45d66e67d9cbbc20ffa0ef258f77b1a", - "source": { - "epoch": "53590", - "root": "0xcce86f29711f2a67412fff3369189a68fb0f048d746bc9c254f32d6e3f92d573" - }, - "target": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - } - }, - "signature": "0x98213903ebafcc76283186dc020a43833f7a91799696ff8b2a780518925b10395eab8e727a4e7467073b767747e0cd06111f20e4c2a8d752ebf858a818fb231e0dbba34ab42312e9a5416bcfe76439dfa689005aaecd63eff082032e1f8628b6" - }, - { - "aggregation_bits": "0x000000160110000084000010400102540000000000100100000410900400000400060040100020020100040000000020000422000000010c100020010004008000104000002000800000080102000000000000000205000104000000800060010002004065", - "data": { - "slot": "1714924", - "index": "31", - "beacon_block_root": "0x0b8d0eb19686541d8d057f2aaaf3a38f612bd17fbd6eab135e1e855ea9b8aae7", - "source": { - "epoch": "53590", - "root": "0xcce86f29711f2a67412fff3369189a68fb0f048d746bc9c254f32d6e3f92d573" - }, - "target": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - } - }, - "signature": "0xb6cc6645c6ea8f9d4ed53f0882ae4c016c08fd37ab49be38ee159fca815f22495870cc2b0b08a51dd3c46b7c974f8b8d0b74cb628690feb9b8ce7dbf43885e62d90c05d6089583264e1038075f1de674af331f3a720b0cb83eea0c2a95257637" - }, - { - "aggregation_bits": "0xf735679ba5ae4279f019cf1444e3d1c79f8e49330bd8f76081156ce515c44b36b0ade33f4a70c23a45f1a01d982d2459c11b7daf39002717ab61d1075bb1b706b4822ec118ad46f85fc6bca8b811d10849065d167d8d716764a28134bcc46ebaf025534578", + "aggregation_bits": "0xfffedf7fffdd8beff9ffe37fbf7ef3ddfbffdfbcdf6e6fdd7ffefff7cfdeffdfff7ffefcffdeff9fffef7fff8f7ffedfeedfadfb72fffbfffdfffbfd9f6fafdffffffff7fdffffedefaf6ffbf9ffffffbffffbfffb7bffffdfdf7cfe7bd6f5fd7ffffdb9f3", + "committee_bits": "0x0101010101010101", "data": { "slot": "1714952", - "index": "12", + "index": "61", "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", "source": { "epoch": "53591", @@ -1764,13 +31,14 @@ "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" } }, - "signature": "0x93832875883841ffa7fc88ce9a92146c1dd8ca60643f81cb514dac64237c86628c5e7ddc990aca34270eb1d7801e576f1501bb8cbc740c2505eedca25b6e1b6818c4348e8d10220b5f1f52f5b1477c7a964285fbd73ac1d13ace5b833d869ca8" + "signature": "0x94f1b4ca8cb85d79879a8748d97f41ad804c0db195f7b7bbb4fcea394c1bf251cc0ddf9c6ceb2295d7176b0a85d4f8e91737845758a1fbcb3c30381b8a0002e1e74924a6658e08291cc53a3a26ca1af3813487c6e04c43ed930c22e250348edc" }, { - "aggregation_bits": "0x0000000000000000800000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000010000000000000000008000000000000000000000000000000000000000800000000000000000000040", + "aggregation_bits": "0xfdf9f7e5ffffffff7dfdf7fdbffbd777ff7be5ff9b7effffffae73ecfffffbdbff1fdfffdffbbff3d7ffffbbfdebbffffb9ffbff7fd7bbfffffffff67f37ef7fffeffcadf7ff7fefffdeaeffd3ff7eff6fee77ffffefffedfd7feeefffbffdf9de6d77df7e", + "committee_bits": "0x0101010101010101", "data": { "slot": "1714952", - "index": "7", + "index": "40", "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", "source": { "epoch": "53591", @@ -1781,13 +49,14 @@ "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" } }, - "signature": "0xa3a3489abfefe61a7535dbb22bc5dffbfb21e712a5ffdbf073cb38f8c1746dfbaba8eaf1bfe4b98b87f08c29e9e5817b125909d42853195ef52b2826ac3366e3aaf4f7289238c0e0c167c7ee0dd33780cd3c1bb1d18924d6335d6444f6b2fcc2" + "signature": "0x8458095fcadb1130365464bc9ed4fdcaf7320c92c36860630578fe649c480274c129461d9845c01567d91d1fcad0cbfe07d98224fd9668a3f618a9aba7bf01a7c67cd3765e15d88bdfdc3ddd33a77d2b03f10dcf6db9cf81b769076b0346c79c" }, { - "aggregation_bits": "0x9515f99eec87ef9dd73ef7cc4fb1eefd77b58fbda863fbefa67e7c2ed8bfbff2c7bdcfbf54fdfff6ef3d117fb9f7275f4ac8fec23345aeceef7f8267d68def637b868d4bfcb8fb5ebef7c426b5bfe78ff8ff672ad735cdeed6df7fd9f75f6cfffff874f57f", + "aggregation_bits": "0xfffea7bfffd7f79fffffb7c5ff7ff77ff7ff9dfeffadfffffbfff7dfbf3d7effb9ebfffd7ffe1fffffbbffefffbfaff7feffef3fdefddfffb7fffdfffffdebeff2fdffffbbefbfd556ffd7bfecf3b5fff7f3fffafff77cfffdf7afffefffffa6dfdef7fe5e", + "committee_bits": "0x0101010101010101", "data": { "slot": "1714952", - "index": "2", + "index": "0", "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", "source": { "epoch": "53591", @@ -1798,13 +67,14 @@ "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" } }, - "signature": "0x9498baf0bf3a2f1446c8f3e0aaabe49f1d49552a73a348f9947576273fe6553249063696b1ac9826596223ad2393d40405503c827502b7213d9c69e17bc6f2041466ffe65fc6bb06c29dd30936cb717fe1f1b40ce20cda88f4a4f306f6ebea4f" + "signature": "0xa2b341bd365df241ad5e2fac0223cb06f6e1cf241b44cf2ac807ccc703a8cfac61d867fce86bf82c53dbd3c3db138b0a01af94de7bb0b457925f823e2b5b6463d5b997127e9942c2afce3ddda58e85e128e999c8c28f5b224a14172bd3e8b0aa" }, { - "aggregation_bits": "0xfffe87bfffd7f79fffffb7c5fb7ff77df5efbddefdacfffefbff775fbf3d3effb9ebfffd7dfe1fbff5bbbfefefbfaff7deffef3fdadddfffb7fff9ffdefdebeff2fd7ffffbefbf9546ffd5beece3b5fff7b1bffafff774fffdf7afffefbfdfaedfdeb7fe5e", + "aggregation_bits": "0xdfffdb9f77ff75fff7d7af7dbfbeebf7fdf7dbeffffff7ffffd1befeff9ffffdf5db5dfffff79fb67bff77e7fdf67fbfddf3ffef7e7dffd3cfffd7fdcffaffffbfffff57f1fafefffebffffe47fffff5fbff7fdbdbfdb7dfeffffff7ffbfefffffaffbe7bf", + "committee_bits": "0x0101010101010101", "data": { "slot": "1714952", - "index": "0", + "index": "6", "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", "source": { "epoch": "53591", @@ -1815,13 +85,14 @@ "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" } }, - "signature": "0x86c7f7bad0178e8304d45e3d243b431fa686ee7b438dd602356ba2f99564f2fcf1cd2cd4b310fa6277c05bae2d1b4e0c17e2d3b2930ee8eb441623f569758066125d10560b6a8f9780efc10ca345c688aea0ede55767dcd736286ffe92b54d70" + "signature": "0x9972475c0adfefa64816aeb9c552db76a463e55b23f0c99112f2b2a5e07028652c64a0960ae39b43cac52933cc7d59fe1184f05266a7f2bdb1a6936c97f8fcade6f91c57951ec6af94f04592477b798df0e65f27bbaee7d95667f5edf8f21715" }, { - "aggregation_bits": "0x0020010000001000032400101240930404200184000010040008050001200000800040020840200100000000010013000424a0088040000100040201020000000000000000080004808804000022020010010000000084000c0082900c0080802020084080", + "aggregation_bits": "0xfff673ffffe8ffdeaf6f7fdffea7ff7fffcdf7ef7c77bd7e7fbedeffeffdffffbffcffbebfbffdfefddffbf7ff7dfffeeeefdbeffdfeeff3ffbefcf7ff7fbaeff6ddfffe3ffdfefaf77ffb3dbffff7f5f7ff9ffffffefbff7ed7ffd1fafef3dbfdffd7fffe", + "committee_bits": "0x0101010101010101", "data": { "slot": "1714952", - "index": "4", + "index": "19", "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", "source": { "epoch": "53591", @@ -1832,116 +103,15 @@ "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" } }, - "signature": "0x8d724e6b14949b2de358c9d32b500e50a318c2b885902c26b636d640de0ddd733f4334690dd021ed9f3cdcde778725830f0d57503613a4b8a3472698a0f0d20d0370efd1ba2c2f76bb3a00a38e763a107270e3d93ec152d01a3756c1368f8db4" - }, - { - "aggregation_bits": "0xffdffffe2fffbf7fffbfbf7f7fffffffff7ffbfdd7fdfffdfcfbf5ffdbfff7dfbfbfaf7cffd6fbffffd3fdfdff7ffeffbf7fbafbffffbfcfffffffcdfadedd9e477bdd7ff7fef77bbf7dfffff7dffffbf7ffffffffffedfffffffbef467b6beffff9ad7f77", - "data": { - "slot": "1714948", - "index": "56", - "beacon_block_root": "0x2d1968818826523eb00cd955a9f790cd6865b1cecd4033e4ad53caa5063ba3f4", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xa43f2ea40cb5c329db3532a4a36e27b8816a8eea311c47a1add25e213e2a52866c0553a72ef9b487b052a1d6cafdf0020faae13878c86a0bda3d2e81c333af1ef2f5ce30d34f5b63d331a1651d8bc1215cdd41a9f8811c2af4fb3d1230f4f34c" - }, - { - "aggregation_bits": "0x0000200000000000000000000000020000000000000000000000000080000000000000000000000000000200000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040", - "data": { - "slot": "1714948", - "index": "7", - "beacon_block_root": "0x2d1968818826523eb00cd955a9f790cd6865b1cecd4033e4ad53caa5063ba3f4", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x957ee1d00097d3088c9630d93c8ef692123d7d7439c59dad5f41be736162576d98937d449ce29b03411a77a21f20cb8103ccdea0b389224493bdce70732be718983cc517c782cbeb80d1878a015d68d9ace2460f555d6b4eb73ddc11fbd89006" - }, - { - "aggregation_bits": "0x0000000000200000000000000080000000000010000000000020000000040000000010000000000000001000000000040000000000040840000000040000000000000000000000000000000100100080000000010000020000100040000000000000000080", - "data": { - "slot": "1714948", - "index": "25", - "beacon_block_root": "0x2d1968818826523eb00cd955a9f790cd6865b1cecd4033e4ad53caa5063ba3f4", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x8a26162fd71fca300d1cff5cd6ec1ee48ee36307294bc9cda6fcbfea90d368d003619d99652e3bcb1a2094ab9d8842f50ea67cc788391553383563f43a80ec0dec5cde1d9629f90cbc383c24750871b33c3164314f4b7ab22e9c4979b96577e6" - }, - { - "aggregation_bits": "0x0020400000000000008000800000000000040000000000000100000000000000000020000008000000000000000000800000000001000000000082000000000000000000000000000000000000000001000400000400000000000000000000000020000040", - "data": { - "slot": "1714949", - "index": "16", - "beacon_block_root": "0x329cea4ccb338cc17baab4bd4639c6909a2ec7d7d19bc4dfd2e478dad2d9f266", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0x925ecb5e955ac3069e167be0774e7571d926bd6073116758725fea9d3dd14868dc259bf231be28fbe94dfe348d36979002caf7bbe3d35356d49dddc83d1e5d691866dda1cd7b451a849aa3bb95a8691c74145e392ead8895015407b22f7e1e57" - }, - { - "aggregation_bits": "0x0000000000000000000000000000000000000000000000000000100000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000020002000000000000000000000000000080", - "data": { - "slot": "1714949", - "index": "45", - "beacon_block_root": "0x329cea4ccb338cc17baab4bd4639c6909a2ec7d7d19bc4dfd2e478dad2d9f266", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xb2d924dff1705df43f15c47a5e5d75f52b2c0ca6b07aa2c3688f13fb2aebc198836b72514c5bafbb78f319608e97e3570d3bc0fc95e4e633c869c98c44db7579018e58d80f6008a7250b5eb994633fd7646f8854b636427079f4492da85ad369" - }, - { - "aggregation_bits": "0xdff7ffffdffffbfd78fdf73ffbeff79e7fbdffeffb9dffdfff7dbd7f77f9fbefffffbdfbf7ffeff6fdfffbebdfeffbfffef9f7bbfffbffffffdffbfdf7fcf7fdbfff6effef7ffeddff8fbfeffdffefffffffffff7fbefeffff7beefff7f5f6f76fbffe9ddf", - "data": { - "slot": "1714951", - "index": "48", - "beacon_block_root": "0x62f336d210f91f20d635cea67d71db0da50b89337bf4aa8d1b42b2365afa56ad", - "source": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - }, - "target": { - "epoch": "53592", - "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" - } - }, - "signature": "0xaefbf6ba247a4c2d48db45a9544ab0ffd2ab9e95beee76cc356afd0b43ab85f892c4b6b4300e0c193a2ac8a37a850cb002fe6451f9190f10976082c049da31e369a4b168b62dfaf7f86d3b7df2a35f2431fd16bb6dfd50492b1ae6f0844d8cdf" + "signature": "0x82bc4e8ff51279d94fa0f29239ae89991ad0261eea98473ef7304212683625f261aa4620ad25fec52d1524d49016d6f41414dce3b3046c131a230f962332b150690916a46cc6832174913ecd90a51f39c25b57bf72d9a329d07793453370f0a2" }, { - "aggregation_bits": "0x0220000000000800000000010000000000000000040000000000080100000000000020000000000000022000000000000003000008000000000000000008005040400000088700000000000800000400000000000008000002080000000800000001040040", + "aggregation_bits": "0x7ffef7befeadafffceffd4dfeedff76fffbffffeefff3fff77bffffdf7fff77bbfbefdb5fffffffe7ffbfd9fff79e7fffefefff7fffffdfffd9ff6f7fe7f7bffffffd83ff9bffafef7fbffaebffafbabfff3bd7eebb9dfdf77ff1fd7ddcfbff7eff7fffd79", + "committee_bits": "0x0101010101010101", "data": { - "slot": "1714951", - "index": "15", - "beacon_block_root": "0x62f336d210f91f20d635cea67d71db0da50b89337bf4aa8d1b42b2365afa56ad", + "slot": "1714952", + "index": "55", + "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", "source": { "epoch": "53591", "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" @@ -1951,14 +121,15 @@ "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" } }, - "signature": "0x929cc926b2d306f5e4d3259300395f9cbfd817169f5caf4c288189221ca890f3bf0ad55e24bb7a1c656c096b66e831b115f3427253cf6cf3edb7cfcefaf6ee2eda6cd46da5dd94aad8eb64d2f8e9a15ba8cab81bc71dcb65ed79eb710ed8b67a" + "signature": "0xaec7f4fa5a4c43fd7e5da13cbcef7f205dc1ab312a2d08ee3144c01379a2c85214f0c6e72a029fea1b380cd42dfd8f120dd7ec5e3dc8c745292a58289457b90527c28896297ee8dadb8c33b4cd2d3eb039049b05e5b147ef9467789f74f3c239" }, { - "aggregation_bits": "0x0000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000200000000000000000000000000000000009000000000000000080000000000000000000000040", + "aggregation_bits": "0xbd3dfbf5fbdb7377cbfa37ffbf7fffb5fff5f676ffffffafff77b7bfadbffffefff4febb6fdf3ffbfaabefddf7dffb7f8fbfefdb7edefcf7fffff7f77fefffffffff77ffff9fffdfbffeef7fffffe9fe97fbefffeff3fff2abfdffff72ffffefffefdfffec", + "committee_bits": "0x0101010101010101", "data": { - "slot": "1714946", - "index": "58", - "beacon_block_root": "0xffb99b0ad2e0c78f257855b1614f62351aff507310cfa0bd312e1762cc8c2887", + "slot": "1714952", + "index": "63", + "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", "source": { "epoch": "53591", "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" @@ -1968,14 +139,15 @@ "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" } }, - "signature": "0x8a3a899061427c4a6904825f32665fe24b1446c034320f497ea55c5cbca80c069f12155fd4b1a5b891b93b75bb23f5d1185cfc0c4fa776b94205ba6b01b3b5899790e1bf7b6be6b3517d3e81eefdfff27913773fc3f6c6dd51bcec8ff3062b9c" + "signature": "0xa5e827e42fe2f1245d99509ea756ce74d26124962771c70d36cdaf8eb75153d7bd3c62e1f10a9724f69e566f3a3d87aa08955bec0f397b728e930b62c532af1f741a7a4557889017e0691de1ddd51f8f6207c185caa98f93432c409f774d4548" }, { - "aggregation_bits": "0x3affd7feb9b7d7bfeb9ff7eff97ff0a7feb6ff75effbfeff6fff1ddeeffffeb77f6bde67f7f7ff9ffdf3dbdffffbdfdef9ffffff3b5edffffddddbff3ff7fffdfb997fafbcbfafffbd857f975e90fff9fdfe74f7d437bfeda6ff1adfff3ffefee7fadfcfb8", + "aggregation_bits": "0xfd77fbdeec9fefbddfbeffffaff7fffdffbdcfffbd67fbeff77fff7efbffbffff77fefbfddfffffeffbdd57fbbf767ff6fc9ffca3f6dbedffffff267deefefff7bc6df6bfdffff5ffffffe2ff5fff7cffeffff6ef77dedffdfffffddff7f6ceffffdfef77f", + "committee_bits": "0x0101010101010101", "data": { - "slot": "1714944", - "index": "32", - "beacon_block_root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee", + "slot": "1714952", + "index": "2", + "beacon_block_root": "0xbc708c8747c7592a23f291c3c155cb8d9bbd6da7fefb64a4311c59ec6854a0de", "source": { "epoch": "53591", "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" @@ -1985,211 +157,7 @@ "root": "0x0abe26187966bcdfe7a6496432fe1f1424fd8f7b4a31899c77ebfa99d5f417ee" } }, - "signature": "0xacdc8906bfd1956cc87efd4976f296c2c735971d227ba0690e14a5123a9478cd2b342a6a756842c07bae53664f7afd4a11d58671b06072b783821a6816ad70ad81a59a18e5380598b62048058269566bde64b136e32f62dda906911e0ea67169" - }, - { - "aggregation_bits": "0xbb2bfaf7b3e95f6f6bcdfffef4ba767e7ff77eff7cbe8fb9f3b7fff7db5f57afdffb660ffdfddb18f76faa795ffefbaf6eaf7fdd77fff569ffffe99adfa6d7efc35dcddf3b7e79f7ed550fea3e8dfbc936e5bf3cfdfaedf6d7f9ffda3ff7ded7fad5d7ff6f", - "data": { - "slot": "1714942", - "index": "57", - "beacon_block_root": "0x1001182f51dbd3fb88719a65cc9910b108acb4cf604597d173cc027928413117", - "source": { - "epoch": "53590", - "root": "0xcce86f29711f2a67412fff3369189a68fb0f048d746bc9c254f32d6e3f92d573" - }, - "target": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - } - }, - "signature": "0x8841e32147f9604c2de09c9519234f0dd414e38699bf7ac1ddd7da81a3c45e34af72cc50b9ee879b4cce39fc7eacd81517ce67f932c7019cc51228f36f87ed7b5f10f7b711b3b1fcb33f30dd1f79c545dc91478e1146d9523fb0076c4795dcf5" - }, - { - "aggregation_bits": "0x9997c70d2ca7a0774556ef41f807b761fee39ec904edc69176aadb5c7d0684c86173b7e532e8334d4c56555bee9fc7cb238d4f7cb6baf127341369cb2871aa45bb0d7c4d143bcfe8aae19a13d5ade00984faf41ef74611eb53abeff0d4f92a48823f5d82af", - "data": { - "slot": "1714921", - "index": "25", - "beacon_block_root": "0x3dc310363e81e57d26686d794315ba5f60411cc2ea0e79944c408b9b2b14613d", - "source": { - "epoch": "53590", - "root": "0xcce86f29711f2a67412fff3369189a68fb0f048d746bc9c254f32d6e3f92d573" - }, - "target": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - } - }, - "signature": "0xac5aef43bc833853bc25f5c07e1f0ad0902dd373d9b6eca0a45f0b8ec1e6c222c63bf48ef09caaf0d065b3b13423aa0301df46819176531a3846264114b69ed1aa1098d914d8d2a843e58ac60bab085572eebe5217ac73842eb359a795c9026a" - }, - { - "aggregation_bits": "0x0100020026400000806020000020010200000400000000001204800800000010002000100010000010844000000804480000009000000100042000600080000000000300100040001202020004280000200100402004000001029008080100000000008260", - "data": { - "slot": "1714922", - "index": "25", - "beacon_block_root": "0x5d53245b0406d686edc3440bee52fd76f0686e342b23892b1fece1dded9842c2", - "source": { - "epoch": "53590", - "root": "0xcce86f29711f2a67412fff3369189a68fb0f048d746bc9c254f32d6e3f92d573" - }, - "target": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - } - }, - "signature": "0x944b6d0cdc16942dd4627a15152d27f310e025e0d45913cec7e8730cb3c62b85d79df58f6dd684ca5d02dfea6200874c0b82f1bd1abaa79f95b4b24e176e1727b1503dadf70f4625a907d9a46dea0449b8070383e5bbd7197c3839de8dec4479" - }, - { - "aggregation_bits": "0x5ffdafef7daffefbffffdffff7eeefbafffffbfdffdf7fffffefffffffeffdfffbffffffffedb7febfffbfbfffefffffffffffffffdffbffffefeffff7ddffdefffffffff9ffffdffffffffd6b7bfbaffffffefeffffffbdfffdfa0bffdfffeffefffff7ff", - "data": { - "slot": "1714932", - "index": "32", - "beacon_block_root": "0xc0c9c3f29cce5609f97ed45edaee5315a3e629590a07c756eb2af46f0556af4f", - "source": { - "epoch": "53590", - "root": "0xcce86f29711f2a67412fff3369189a68fb0f048d746bc9c254f32d6e3f92d573" - }, - "target": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - } - }, - "signature": "0x87305e7529862862103d4502d306a358032c7273426bc77a0c25daff3051fb844ce0f876a5276fecd02ebd1765775837141c512e1234c3f6f54c5d39f8e1d6c5282c18758109533cc0e532c060de2e1d18bd535a7bd0ef7b5d3807a8944e25ef" - }, - { - "aggregation_bits": "0xffffbeffebfddf799fffbd7ebf8b7ff53fffd7f3fffdffeb7ffdeffdeffdffff7fdffdffdffbdfffff7dff7ff9ffcefb8fd76fbffddd7ffe5ffffe77fafdfbcffe7fbfadefddf7ffefffffff9fffc1ffffffebb7fec2f47f76fb7fbe7fdffbdffdfff7fded", - "data": { - "slot": "1714933", - "index": "60", - "beacon_block_root": "0x193fdb81165ed2620c277daf1adf746e73dd93334a502ecf5d03b7ff7a3adcdb", - "source": { - "epoch": "53590", - "root": "0xcce86f29711f2a67412fff3369189a68fb0f048d746bc9c254f32d6e3f92d573" - }, - "target": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - } - }, - "signature": "0x87dc2cdce51769f74b7554f7b67972501f2eb2ae254aa7d1330945a9766f444c8be89a0ba80438e3e73e05f2817191b10ae0f333468d043c6be4839be47643dc36ba5965c800a9a7a31c2b340219b783f95ba4d57d36f08908011d3ad16bed48" - }, - { - "aggregation_bits": "0xeafbbbfafffffffffefdfdbfff7fffb7ffbfffffbfbbdf7ff4fdfd7feb6ce8dffd3f9fff5ffffb5bfefeffbddfffdde5f7efff7fde7dff6ffe7baf7fffdeff7ffdf6f7dfbbbfebe9f7fbdeffbdfffffddbfbff7ea7fefbfdfe75fbfc9e3ffbfdfeffffcf7e", - "data": { - "slot": "1714925", - "index": "32", - "beacon_block_root": "0xc539d71c6a833d994b4ff309aca653c5777ded3cf854b2bc02b7e23f1ae40729", - "source": { - "epoch": "53590", - "root": "0xcce86f29711f2a67412fff3369189a68fb0f048d746bc9c254f32d6e3f92d573" - }, - "target": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - } - }, - "signature": "0x8ee9a9c55cf0588ca200361ba997b1bf8192f5ed48b8dcc48bb72069233921f35e07babfa282152ada896a13f2f4935f17db7b19c1083e7feaca19c6d020c563b0357e280605ecdd5d0aa6411c026ee577aeb017f8f5761410367fecfd277b93" - }, - { - "aggregation_bits": "0xf7fff7fffbebffff6ff6feffffef5bfffffefbefebfb77fffb7f3fffffbffb7ffffff9affdefffffddfffbdffffffffdfdeeff7fffbffff7dfebfdbff1fffffdafcefffbffffc7dbfffffbfffbebafdefffddddfb7ffdf6ecf7fd7bfdefffefffbfbf3ffbf", - "data": { - "slot": "1714933", - "index": "57", - "beacon_block_root": "0x193fdb81165ed2620c277daf1adf746e73dd93334a502ecf5d03b7ff7a3adcdb", - "source": { - "epoch": "53590", - "root": "0xcce86f29711f2a67412fff3369189a68fb0f048d746bc9c254f32d6e3f92d573" - }, - "target": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - } - }, - "signature": "0xabdcf99b329c1ee06d5bb6c20d9c70dd94e36ad73b2a7ddd34f9504d24e4a733657d49b1ee9edea02fee4d2de5ed1d691466a29a274265b078ee1ad8d4e9521613a2f592a1b9debdd1644565cb86559e992b85a59dd54d26458c799416ac428b" - }, - { - "aggregation_bits": "0xbfbe7fffafd5d6f7bafdefb7bbf99eebf3f7e7e76fffbfdbfff6fff77ffcffeffcfffefb3fd6ebffae8bff2a73eefffb7df5fbeef7ff68ffbf77fb7fff5dacefee92ffebbcdf7cf7ffbfddfdffffffb25a4935fdfd7effbffbeafeaf5bffbfcfd9d7bf3f6e", - "data": { - "slot": "1714921", - "index": "56", - "beacon_block_root": "0x3dc310363e81e57d26686d794315ba5f60411cc2ea0e79944c408b9b2b14613d", - "source": { - "epoch": "53590", - "root": "0xcce86f29711f2a67412fff3369189a68fb0f048d746bc9c254f32d6e3f92d573" - }, - "target": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - } - }, - "signature": "0x831b20dc1d26d90a04331790760bab556b9153a7a36f11c97454b8b9f359c9ae270c95aa45eac04110fb94cf32118a6305bc297bd235d094df096d3351f83464d220a0e4e7aacfdfa9eba6847e41f05fce99ae72d75e766a0c744d38289d93f0" - }, - { - "aggregation_bits": "0x70f7bffd8f586ed3f197fe3bfd6d77dfb3b5faffbff9f7ff7affdfdfe7ff73efd8df9f6dedf54ff7ffdfebff3f77fefdb8edfbb1a9e3f6ffbe7fe7d715f7bfbfe6cd95ff5dbd6fefff6e5ffff7beff7ffbedbfff9fbb77e7fffcffdb7fff3f23dbbff7adbf", - "data": { - "slot": "1714921", - "index": "45", - "beacon_block_root": "0x3dc310363e81e57d26686d794315ba5f60411cc2ea0e79944c408b9b2b14613d", - "source": { - "epoch": "53590", - "root": "0xcce86f29711f2a67412fff3369189a68fb0f048d746bc9c254f32d6e3f92d573" - }, - "target": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - } - }, - "signature": "0xa01d6efa22580bda48f95cc87529c982a953c4d9f884d1eb068de6589bd2ef6511c011d6ac2ce8f5ce467e6c35099a2219003a5598731b400dd4f397e0f2f2bb60f6a9bfb9496d2a158a4410a7a1dd11fa29dbb0ea375fe91d6950ad6935344a" - }, - { - "aggregation_bits": "0xffff76fff7de5effffffff7feffdefe775edf7bfddffffffefaeff3bff97fffffff7dcff3f779abffbfaffffffbfff3f67ee9e3f77b737f78f8fbdffffffffefff6effdffdf7f9bfa7fd76f6efeffebffbf27ef7dffbffbbff7fcf9ffff9ff7fffbfffef7e", - "data": { - "slot": "1714931", - "index": "35", - "beacon_block_root": "0xc0c9c3f29cce5609f97ed45edaee5315a3e629590a07c756eb2af46f0556af4f", - "source": { - "epoch": "53590", - "root": "0xcce86f29711f2a67412fff3369189a68fb0f048d746bc9c254f32d6e3f92d573" - }, - "target": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - } - }, - "signature": "0x8ba6d8fb0c36da5582bfdafadb47e5e3eac774c791560e68c3549da4f756da975e65757caeec1b93f818964ac65e5b6713ba9048abcf72563cc98071a7124bd6135936f10b950ccc2452de72df2e3b89f217434395fac6e06984b18986596bf8" - }, - { - "aggregation_bits": "0x828000000000200010188400001020020000640400000000800030800608100000000040c01050010803000104028c084024010084000000002084000000054000400004a10000040904000004000020000008040050000002024080100000220000000082", - "data": { - "slot": "1714924", - "index": "50", - "beacon_block_root": "0x0b8d0eb19686541d8d057f2aaaf3a38f612bd17fbd6eab135e1e855ea9b8aae7", - "source": { - "epoch": "53590", - "root": "0xcce86f29711f2a67412fff3369189a68fb0f048d746bc9c254f32d6e3f92d573" - }, - "target": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - } - }, - "signature": "0xb2cad51b95f23acbed48d84ebafe8a8607aff2e43848ab399f3d5fc87b64884b05fb06f76258d8c1ff8416ec0ad1ea3f16d09b2d31a7331f7d44165ad95b0d979fdf6609efa172d6359f52ed7a5b5497643f19f091769accb5b349e7413bdbbb" - }, - { - "aggregation_bits": "0xf7bffefffff7fdff7eedffff77ff73fffef5fe77ff7fffffffffefffdfffefffffeffbff7efdfeff7f5fffdfdf7ffffffdeffdffeff5ffffffffeffcefb7ffffbfffffff7dfffffffdeffffffef7bfffffffddffbfff7fdedfbffffb7bf97ffdfbbfebbf7f", - "data": { - "slot": "1714925", - "index": "59", - "beacon_block_root": "0xc539d71c6a833d994b4ff309aca653c5777ded3cf854b2bc02b7e23f1ae40729", - "source": { - "epoch": "53590", - "root": "0xcce86f29711f2a67412fff3369189a68fb0f048d746bc9c254f32d6e3f92d573" - }, - "target": { - "epoch": "53591", - "root": "0xfd33f7c16f0653c3f61acab881e52467b2b1b9908adedcf146f75caefff4b789" - } - }, - "signature": "0xa6eda3a5ea659b929ef2e0841f6ccd850d68f8ec8a5cb3be20bfeb5641664f40170c25a067b0d54896e9ee5152677d720778d5acae62268b967af9e762745dfb87d6ab59d9c6b4fe9236074fd8df22232da9a82a3ca6b29a0c0c487c050c8062" + "signature": "0x9459d789f38d5feccc20ee94be507198a8f25fe3b69a02e564531244eb118490dbcea7ed66481c3c93196d8c189bddad0566cf1507623b6f89421bd742fd974e245e6c6b47f98016b86025ee25f53afc64d526097ff1a37abe6951226d71cd9e" } ], "deposits": [], @@ -2225,7 +193,32 @@ "0xa49c576627561ec9ae1ef7494e7cee7ede7fa7695d4462436c3e549cc3ce78674b407e8b5f8903b80f77a68814642d6c", "0x83155fbeb04758d267193800fb89fa30eb13ac0e217005ae7e271733205ca8a6cd80fba08bf5c9a4a5cc0c9d463ac633", "0xa20c71d1985996098aa63e8b5dc7b7fedb70de31478fe309dad3ac0e9b6d28d82be8e5e543021a0203dc785742e94b2f" - ] + ], + "execution_requests": { + "deposits": [ + { + "pubkey": "0x0e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "withdrawal_credentials": "0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f", + "amount": "100", + "signature": "0x100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "index": "1" + } + ], + "withdrawals": [ + { + "source_address": "0x1100000000000000000000000000000000000000", + "validator_pubkey": "0x120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "amount": "1" + } + ], + "consolidations": [ + { + "source_address": "0x1200000000000000000000000000000000000000", + "source_pubkey": "0x120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "target_pubkey": "0x110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + } + ] + } } }, "signature": "0xa9f158bca1d9d6b93a9104f48bd2d1e7689bef3fc974651fc755cc6f50d3649c5153a342a12f95cd8f9cac4f90144985189f498a7e0e1cb202ed5e7c98f3f504f371a53b9293bdd973fbb019c91242f808072d0ffcd9d17e2404baea3190fd18" From bbb260b985f2e6857c0ba76f008631d519496817 Mon Sep 17 00:00:00 2001 From: eltitanb Date: Fri, 11 Jul 2025 18:24:55 +0100 Subject: [PATCH 05/12] fix tests --- crates/common/src/config/mux.rs | 23 +- crates/common/src/pbs/error.rs | 2 +- crates/common/src/pbs/types/beacon_block.rs | 3 +- crates/common/src/pbs/types/get_header.rs | 19 +- .../types/testdata/get-header-response.json | 14 +- .../types/testdata/get-header-response.ssz | Bin 2448 -> 1224 bytes ...signed-blinded-beacon-block-electra-2.json | 34 +-- .../signed-blinded-beacon-block-electra-2.ssz | Bin 8618 -> 4309 bytes crates/pbs/src/mev_boost/get_header.rs | 22 +- crates/signer/src/manager/local.rs | 13 +- tests/data/signed_blinded_block_holesky.json | 10 +- tests/data/ssv_valid.json | 6 +- tests/src/mock_relay.rs | 22 +- tests/src/mock_validator.rs | 4 +- ...signed-blinded-beacon-block-electra-2.json | 223 ------------------ 15 files changed, 93 insertions(+), 302 deletions(-) delete mode 100644 tests/src/signed-blinded-beacon-block-electra-2.json diff --git a/crates/common/src/config/mux.rs b/crates/common/src/config/mux.rs index 04e1410b..51e84495 100644 --- a/crates/common/src/config/mux.rs +++ b/crates/common/src/config/mux.rs @@ -14,7 +14,7 @@ use alloy::{ }; use eyre::{bail, ensure, Context}; use reqwest::Client; -use serde::{Deserialize, Serialize}; +use serde::{Deserialize, Deserializer, Serialize}; use tracing::{debug, info, warn}; use url::Url; @@ -393,12 +393,29 @@ struct SSVResponse { pagination: SSVPagination, } -#[derive(Deserialize)] struct SSVValidator { - #[serde(rename = "public_key")] pubkey: BlsPublicKey, } +impl<'de> Deserialize<'de> for SSVValidator { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + #[derive(Deserialize)] + struct SSVValidator { + public_key: String, + } + + let s = SSVValidator::deserialize(deserializer)?; + let bytes = alloy::hex::decode(&s.public_key).map_err(serde::de::Error::custom)?; + let pubkey = BlsPublicKey::deserialize(&bytes) + .map_err(|e| serde::de::Error::custom(format!("invalid BLS public key: {e:?}")))?; + + Ok(Self { pubkey }) + } +} + #[derive(Deserialize)] struct SSVPagination { total: usize, diff --git a/crates/common/src/pbs/error.rs b/crates/common/src/pbs/error.rs index 2e8667e4..2ca40e38 100644 --- a/crates/common/src/pbs/error.rs +++ b/crates/common/src/pbs/error.rs @@ -63,7 +63,7 @@ pub enum ValidationError { #[error("block hash mismatch: expected {expected} got {got}")] BlockHashMismatch { expected: B256, got: B256 }, - #[error("mismatch in KZG commitments: exepcted_blobs: {expected_blobs} got_blobs: {got_blobs} got_commitments: {got_commitments} got_proofs: {got_proofs}")] + #[error("mismatch in KZG commitments: expected_blobs: {expected_blobs} got_blobs: {got_blobs} got_commitments: {got_commitments} got_proofs: {got_proofs}")] KzgCommitments { expected_blobs: usize, got_blobs: usize, diff --git a/crates/common/src/pbs/types/beacon_block.rs b/crates/common/src/pbs/types/beacon_block.rs index 77451f31..ad081314 100644 --- a/crates/common/src/pbs/types/beacon_block.rs +++ b/crates/common/src/pbs/types/beacon_block.rs @@ -165,8 +165,7 @@ mod tests { assert!(matches!(block_json.message, BlindedBeaconBlock::Electra(_))); let data_ssz = include_bytes!("testdata/signed-blinded-beacon-block-electra-2.ssz"); - let data_ssz = alloy::primitives::hex::decode(data_ssz).unwrap(); - let block_ssz = test_encode_decode_ssz::(&data_ssz); + let block_ssz = test_encode_decode_ssz::(data_ssz); assert!(matches!(block_ssz.message, BlindedBeaconBlock::Electra(_))); assert_eq!(block_json.as_ssz_bytes(), data_ssz); diff --git a/crates/common/src/pbs/types/get_header.rs b/crates/common/src/pbs/types/get_header.rs index f53998c5..e8e7fc7d 100644 --- a/crates/common/src/pbs/types/get_header.rs +++ b/crates/common/src/pbs/types/get_header.rs @@ -104,7 +104,7 @@ mod tests { }; #[test] - // from the builder api spec, the signature is a dummy so it's not checked + // from the builder api spec, with signature fixed to the correct pubkey fn test_get_header_electra() { let data = r#"{ "version": "electra", @@ -135,32 +135,32 @@ mod tests { "execution_requests": { "deposits": [ { - "pubkey": "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a", + "pubkey": "0x911f24ad11078aad2b28ff9dcb4651a0b686e3972b2b4190273f35d416bf057dbd95553d7a0edb107b1a5e1b211da8c4", "withdrawal_credentials": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", "amount": "1", - "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505", + "signature": "0xb4f92cd90de8e4b67debeb0379f08d0e6d3046e67e824e6ed63cd841abc9999c8b123a780e34a480d4ef13466b6241e30000b047d27de43fcf475fc4e69da2d26929cec97742892346f53e78f973bbe8095285f05a8ea60b118cdd1e6a704c94", "index": "1" } ], "withdrawals": [ { "source_address": "0xabcf8e0d4e9587369b2301d0790347320302cc09", - "validator_pubkey": "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a", + "validator_pubkey": "0x911f24ad11078aad2b28ff9dcb4651a0b686e3972b2b4190273f35d416bf057dbd95553d7a0edb107b1a5e1b211da8c4", "amount": "1" } ], "consolidations": [ { "source_address": "0xabcf8e0d4e9587369b2301d0790347320302cc09", - "source_pubkey": "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a", - "target_pubkey": "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a" + "source_pubkey": "0x911f24ad11078aad2b28ff9dcb4651a0b686e3972b2b4190273f35d416bf057dbd95553d7a0edb107b1a5e1b211da8c4", + "target_pubkey": "0x911f24ad11078aad2b28ff9dcb4651a0b686e3972b2b4190273f35d416bf057dbd95553d7a0edb107b1a5e1b211da8c4" } ] }, "value": "1", - "pubkey": "0x86b1cea87eed94cad99244356abcd83995947670f0553a1d3fe83c4a9e8116f4891fb1c51db232e736be1cb3327164bc" + "pubkey": "0xac0a230bd98a766b8e4156f0626ee679dd280dee5b0eedc2b9455ca3dacc4c7618da5010b9db609450a712f095c9f7a5" }, - "signature": "0x8addecd35e0ffe27b74e41aff2836527e6fea0efdb46dbb0f7436f5087d0cd5665bd16d924f640fc928cdba0173971e400dc603dbd6310bfb6f249c1554b044fe06ae4cf5d5f452f3ff19d9d130809b34d3d3abdca3d192c839ba2ac91129c15" + "signature": "0x8aeb4642fb2982039a43fd6a6d9cc0ebf7598dbf02343c4617d9a68d799393c162492add63f31099a25eacc2782ba27a190e977a8c58760b6636dccb503d528b3be9e885c93d5b79699e68fcca870b0c790cdb00d67604d8b4a3025ae75efa2f" } }"#; @@ -187,9 +187,8 @@ mod tests { >(&data_json); let data_ssz = include_bytes!("testdata/get-header-response.ssz"); - let data_ssz = alloy::primitives::hex::decode(data_ssz).unwrap(); test_encode_decode_ssz::>( - &data_ssz, + data_ssz, ); assert_eq!(block_json.as_ssz_bytes(), data_ssz); diff --git a/crates/common/src/pbs/types/testdata/get-header-response.json b/crates/common/src/pbs/types/testdata/get-header-response.json index 0198af6a..96ee57af 100644 --- a/crates/common/src/pbs/types/testdata/get-header-response.json +++ b/crates/common/src/pbs/types/testdata/get-header-response.json @@ -25,30 +25,30 @@ "execution_requests": { "deposits": [ { - "pubkey": "0x0e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "pubkey": "0xac0a230bd98a766b8e4156f0626ee679dd280dee5b0eedc2b9455ca3dacc4c7618da5010b9db609450a712f095c9f7a5", "withdrawal_credentials": "0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f", "amount": "100", - "signature": "0x100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "signature": "0x8aeb4642fb2982039a43fd6a6d9cc0ebf7598dbf02343c4617d9a68d799393c162492add63f31099a25eacc2782ba27a190e977a8c58760b6636dccb503d528b3be9e885c93d5b79699e68fcca870b0c790cdb00d67604d8b4a3025ae75efa2f", "index": "1" } ], "withdrawals": [ { "source_address": "0x1100000000000000000000000000000000000000", - "validator_pubkey": "0x120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "validator_pubkey": "0xac0a230bd98a766b8e4156f0626ee679dd280dee5b0eedc2b9455ca3dacc4c7618da5010b9db609450a712f095c9f7a5", "amount": "1" } ], "consolidations": [ { "source_address": "0x1200000000000000000000000000000000000000", - "source_pubkey": "0x120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "target_pubkey": "0x110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "source_pubkey": "0xac0a230bd98a766b8e4156f0626ee679dd280dee5b0eedc2b9455ca3dacc4c7618da5010b9db609450a712f095c9f7a5", + "target_pubkey": "0xac0a230bd98a766b8e4156f0626ee679dd280dee5b0eedc2b9455ca3dacc4c7618da5010b9db609450a712f095c9f7a5" } ] }, "value": "11", - "pubkey": "0x120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "pubkey": "0xac0a230bd98a766b8e4156f0626ee679dd280dee5b0eedc2b9455ca3dacc4c7618da5010b9db609450a712f095c9f7a5" }, - "signature": "0x010203040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "signature": "0x8aeb4642fb2982039a43fd6a6d9cc0ebf7598dbf02343c4617d9a68d799393c162492add63f31099a25eacc2782ba27a190e977a8c58760b6636dccb503d528b3be9e885c93d5b79699e68fcca870b0c790cdb00d67604d8b4a3025ae75efa2f" } \ No newline at end of file diff --git a/crates/common/src/pbs/types/testdata/get-header-response.ssz b/crates/common/src/pbs/types/testdata/get-header-response.ssz index 59133c48265668b5513a9bc04f3cbefa6761ff40..7d9c12c554f1ab58f1ff8735db4fbdb0d9cf47bd 100644 GIT binary patch literal 1224 zcmYdcU|{Ha?dJ4bvx#|@^WUu8IR{>UkL=ygWMbncesfuG<>bi+lRUNVCVv)~xhQVU zp$hFqRg!$ut9l~JxYNw;oDQ%J>b8FQqV=S0bY_bxCv&y>~yzip<-X7ZN8ngJ;8J{wV zTLA()ZzoI%ST6Ko>dEg*8Sxnglml9c0hlpFPz6{}xfncF43Uu~z(&Bk4v(O*!f6Xu z+0Y^frY|u~^8_(GfRVxr7QsyrN+&$HwSr{`$)`Z|pMcUOsl_FXOw5F$9>rFW9cO@8 l0_a^*(=9&%0COL$^Cm3+2%`85!Xed9FtdcHU>2!%0|1Zx<^uo# literal 2448 zcmeHIZ4SdA2))u%(c0r|{kZ=TW>!qCi60GJlP%L91dt~W6&+z43K|AcW8?P-J8ii> zeBcqr%o0x-2lYmiVN|14)!TOV=4aYa)fLj4VXNqW=dV}5$p{h_jpJJx&AelJcv8!* z&l-AkG)4=>evrgO-zh2VC*VGHYR`1BFy3YFc=9PYFp#r@87S2Hv;P6}m{=;$r<UkL=ygWMbncesfuG<>bi+lRUNVCVv)~xhQVU zp$hFqRg!$ut9l~JxYNw;oDQ%J>b8FQqV=S0bY( z_A)u}x{qh|LbYFy-x^potNK5l-@9sAu~58&)0q&UF|>9w&zh?jC#FdNxEYOpi885p+m zGB70aF)&O7;%ca&CxCvT2cUJ_4>$j?03(G1h*^N~^8`qXLXs{6EV>w(m|0la*f}`4 zxOsT__yq)oghfQf#3dx9q-A8~$nP+-aQO)) z52JCZ8z{en(!d)awlsja3>HSj#yuf_!Q^4|fcc-1NWeq@FcSbQ1OO`mz(xSD6960p z04D*!MF4OU06YW$F9E z05SxCECC=#0LT*n3Iu>60kDQknfqo}S$3ae*oUONXO(v~c;7|yy*;$kHD>XxGd^V! zw*mxq-cFbjuw3ZF)RW(r5?fHxx`2l@PGAKrt?h%gL1Ffx(?9DZcv$(OHXw^zXGi+R z?5qEREQZWxxwmCsX6VDk$YP^xL{ut^nT>)Ts8X{$Mwhle)ehar|BIQ zyf)o3F)4=+<7h{(ZTCif!3*u%vA-Yv{yn(fSB8U(Ex=aC1Z;>*2#8S@L_|0X65^u; z8PU}OY#U9ei0l?LBfYJ z4Az2#{MUkv?AZd89!ywjS{5|q{T6iW8Y~#tb6B9*u~;zK1WV{$*P4tMbuDYgcb0Qm z>A!Y{ddBY?j~^>1Z~S-fPX1U2y~@BWsC#E*1c5ZvLmBW1F=?@d;z#IB(?nVQYV$*z zZyHMosQVwbMOTUa&i`o=$P(E#8M++h@Jv_VKS|im7;Y=^$xAPfbsa~3SMzSQp@+4vcE| zW;=`rPk@skoC2k-{`m|OzmM;iz%9Ptzy56HR=Mii6|v!%5u8!DZ`_)9 diff --git a/crates/pbs/src/mev_boost/get_header.rs b/crates/pbs/src/mev_boost/get_header.rs index 0021a09b..f5d109e0 100644 --- a/crates/pbs/src/mev_boost/get_header.rs +++ b/crates/pbs/src/mev_boost/get_header.rs @@ -509,7 +509,7 @@ mod tests { pbs::{error::ValidationError, BlsSecretKey, EMPTY_TX_ROOT_HASH}, signature::sign_builder_message, types::Chain, - utils::timestamp_of_slot_start_sec, + utils::{timestamp_of_slot_start_sec, TestRandomSeed}, }; use super::{validate_header_data, *}; @@ -573,24 +573,10 @@ mod tests { #[test] fn test_validate_signature() { - let secret_key = BlsSecretKey::deserialize(&[ - 0, 136, 227, 100, 165, 57, 106, 129, 181, 15, 235, 189, 200, 120, 70, 99, 251, 144, - 137, 181, 230, 124, 189, 193, 115, 153, 26, 0, 197, 135, 103, 63, - ]) - .unwrap(); + let secret_key = BlsSecretKey::test_random(); let pubkey = secret_key.public_key(); - - let wrong_pubkey = BlsPublicKey::deserialize(&[ - 0, 136, 227, 100, 165, 57, 106, 129, 181, 15, 235, 189, 200, 120, 70, 99, 251, 144, - 137, 181, 230, 124, 189, 193, 115, 153, 26, 0, 197, 135, 103, 65, - ]) - .unwrap(); - - let wrong_signature = BlsSignature::deserialize(&[ - 0, 136, 227, 100, 165, 57, 106, 129, 181, 15, 235, 189, 200, 120, 70, 99, 251, 144, - 137, 181, 230, 124, 189, 193, 115, 153, 26, 0, 197, 135, 103, 65, - ]) - .unwrap(); + let wrong_pubkey = BlsPublicKey::test_random(); + let wrong_signature = BlsSignature::test_random(); let message = B256::random(); diff --git a/crates/signer/src/manager/local.rs b/crates/signer/src/manager/local.rs index df6743df..f2b6cb9f 100644 --- a/crates/signer/src/manager/local.rs +++ b/crates/signer/src/manager/local.rs @@ -290,7 +290,8 @@ mod tests { mod test_proxy_bls { use cb_common::{ - constants::COMMIT_BOOST_DOMAIN, signature::compute_domain, signer::verify_bls_signature, + constants::COMMIT_BOOST_DOMAIN, signature::compute_domain, + signer::verify_bls_signature, utils::TestRandomSeed, }; use super::*; @@ -327,9 +328,7 @@ mod tests { .await .unwrap(); - let mut m = signed_delegation.signature.serialize(); - m[0] = m[0].overflowing_add(1).0; - signed_delegation.signature = BlsSignature::deserialize(&m).unwrap(); + signed_delegation.signature = BlsSignature::test_random(); let validation_result = signed_delegation.validate(CHAIN); @@ -366,7 +365,7 @@ mod tests { mod test_proxy_ecdsa { use cb_common::{ constants::COMMIT_BOOST_DOMAIN, signature::compute_domain, - signer::verify_ecdsa_signature, + signer::verify_ecdsa_signature, utils::TestRandomSeed, }; use super::*; @@ -403,9 +402,7 @@ mod tests { .await .unwrap(); - let mut m = signed_delegation.signature.serialize(); - m[0] = m[0].overflowing_add(1).0; - signed_delegation.signature = BlsSignature::deserialize(&m).unwrap(); + signed_delegation.signature = BlsSignature::test_random(); let validation_result = signed_delegation.validate(CHAIN); diff --git a/tests/data/signed_blinded_block_holesky.json b/tests/data/signed_blinded_block_holesky.json index f70a69ad..14aeb814 100644 --- a/tests/data/signed_blinded_block_holesky.json +++ b/tests/data/signed_blinded_block_holesky.json @@ -197,25 +197,25 @@ "execution_requests": { "deposits": [ { - "pubkey": "0x0e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "pubkey": "0xac0a230bd98a766b8e4156f0626ee679dd280dee5b0eedc2b9455ca3dacc4c7618da5010b9db609450a712f095c9f7a5", "withdrawal_credentials": "0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f", "amount": "100", - "signature": "0x100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "signature": "0x8aeb4642fb2982039a43fd6a6d9cc0ebf7598dbf02343c4617d9a68d799393c162492add63f31099a25eacc2782ba27a190e977a8c58760b6636dccb503d528b3be9e885c93d5b79699e68fcca870b0c790cdb00d67604d8b4a3025ae75efa2f", "index": "1" } ], "withdrawals": [ { "source_address": "0x1100000000000000000000000000000000000000", - "validator_pubkey": "0x120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "validator_pubkey": "0xac0a230bd98a766b8e4156f0626ee679dd280dee5b0eedc2b9455ca3dacc4c7618da5010b9db609450a712f095c9f7a5", "amount": "1" } ], "consolidations": [ { "source_address": "0x1200000000000000000000000000000000000000", - "source_pubkey": "0x120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "target_pubkey": "0x110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "source_pubkey": "0xac0a230bd98a766b8e4156f0626ee679dd280dee5b0eedc2b9455ca3dacc4c7618da5010b9db609450a712f095c9f7a5", + "target_pubkey": "0xac0a230bd98a766b8e4156f0626ee679dd280dee5b0eedc2b9455ca3dacc4c7618da5010b9db609450a712f095c9f7a5" } ] } diff --git a/tests/data/ssv_valid.json b/tests/data/ssv_valid.json index e19b13e6..20fa9baa 100644 --- a/tests/data/ssv_valid.json +++ b/tests/data/ssv_valid.json @@ -2,7 +2,7 @@ "validators": [ { "id": 554991, - "public_key": "967ba17a3e7f82a25aa5350ec34d6923e28ad8237b5a41efe2c5e325240d74d87a015bf04634f21900963539c8229b2a", + "public_key": "0x967ba17a3e7f82a25aa5350ec34d6923e28ad8237b5a41efe2c5e325240d74d87a015bf04634f21900963539c8229b2a", "cluster": "0xf7c1283eb0c0f76b5fa84c7541d8d4d27751b4083a5e8dcb8ac9e72bb7f559b8", "owner_address": "0xB2EE025B1d129c61E77223bAb42fc65b29B16243", "status": "Inactive", @@ -31,7 +31,7 @@ }, { "id": 554992, - "public_key": "ac769e8cec802e8ffee34de3253be8f438a0c17ee84bdff0b6730280d24b5ecb77ebc9c985281b41ee3bda8663b6658c", + "public_key": "0xac769e8cec802e8ffee34de3253be8f438a0c17ee84bdff0b6730280d24b5ecb77ebc9c985281b41ee3bda8663b6658c", "cluster": "0xf7c1283eb0c0f76b5fa84c7541d8d4d27751b4083a5e8dcb8ac9e72bb7f559b8", "owner_address": "0xB2EE025B1d129c61E77223bAb42fc65b29B16243", "status": "Inactive", @@ -60,7 +60,7 @@ }, { "id": 554994, - "public_key": "8c866a5a05f3d45c49b457e29365259021a509c5daa82e124f9701a960ee87b8902e87175315ab638a3d8b1115b23639", + "public_key": "0x8c866a5a05f3d45c49b457e29365259021a509c5daa82e124f9701a960ee87b8902e87175315ab638a3d8b1115b23639", "cluster": "0xf7c1283eb0c0f76b5fa84c7541d8d4d27751b4083a5e8dcb8ac9e72bb7f559b8", "owner_address": "0xB2EE025B1d129c61E77223bAb42fc65b29B16243", "status": "Inactive", diff --git a/tests/src/mock_relay.rs b/tests/src/mock_relay.rs index ae46464e..b058327d 100644 --- a/tests/src/mock_relay.rs +++ b/tests/src/mock_relay.rs @@ -16,8 +16,9 @@ use axum::{ }; use cb_common::{ pbs::{ - BlsSecretKey, ExecutionPayloadHeaderMessageElectra, ExecutionRequests, GetHeaderParams, - GetHeaderResponse, SignedExecutionPayloadHeader, SubmitBlindedBlockResponse, + BlindedBeaconBlock, BlsSecretKey, ExecutionPayloadHeaderMessageElectra, ExecutionRequests, + GetHeaderParams, GetHeaderResponse, KzgProof, SignedBlindedBeaconBlock, + SignedExecutionPayloadHeader, SubmitBlindedBlockResponse, VersionedResponse, BUILDER_API_PATH, GET_HEADER_PATH, GET_STATUS_PATH, REGISTER_VALIDATOR_PATH, SUBMIT_BLOCK_PATH, }, @@ -149,12 +150,25 @@ async fn handle_register_validator( StatusCode::OK.into_response() } -async fn handle_submit_block(State(state): State>) -> Response { +async fn handle_submit_block( + State(state): State>, + Json(submit_block): Json, +) -> Response { state.received_submit_block.fetch_add(1, Ordering::Relaxed); if state.large_body() { (StatusCode::OK, Json(vec![1u8; 1 + MAX_SIZE_SUBMIT_BLOCK_RESPONSE])).into_response() } else { - let response = SubmitBlindedBlockResponse::default(); + let VersionedResponse::Electra(mut response) = SubmitBlindedBlockResponse::default(); + response.execution_payload.block_hash = submit_block.block_hash(); + + let BlindedBeaconBlock::Electra(body) = submit_block.message; + + response.blobs_bundle.blobs.push(Default::default()).unwrap(); + response.blobs_bundle.commitments = body.body.blob_kzg_commitments; + response.blobs_bundle.proofs.push(KzgProof([0; 48])).unwrap(); + + let response = VersionedResponse::Electra(response); + (StatusCode::OK, Json(response)).into_response() } } diff --git a/tests/src/mock_validator.rs b/tests/src/mock_validator.rs index 3c898ad7..a70ff84d 100644 --- a/tests/src/mock_validator.rs +++ b/tests/src/mock_validator.rs @@ -53,6 +53,8 @@ impl MockValidator { } pub fn load_test_signed_blinded_block() -> SignedBlindedBeaconBlock { - let data_json = include_str!("signed-blinded-beacon-block-electra-2.json"); + let data_json = include_str!( + "../../crates/common/src/pbs/types/testdata/signed-blinded-beacon-block-electra-2.json" + ); serde_json::from_str(data_json).unwrap() } diff --git a/tests/src/signed-blinded-beacon-block-electra-2.json b/tests/src/signed-blinded-beacon-block-electra-2.json deleted file mode 100644 index 81c8743b..00000000 --- a/tests/src/signed-blinded-beacon-block-electra-2.json +++ /dev/null @@ -1,223 +0,0 @@ -{ - "message": { - "body": { - "attestations": [ - { - "aggregation_bits": "0x01", - "committee_bits": "0x0101010101010101", - "data": { - "beacon_block_root": "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20", - "index": "1", - "slot": "12345", - "source": { - "epoch": "1", - "root": "0x0200000000000000000000000000000000000000000000000000000000000000" - }, - "target": { - "epoch": "2", - "root": "0x0200000000000000000000000000000000000000000000000000000000000000" - } - }, - "signature": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - } - ], - "attester_slashings": [ - { - "attestation_1": { - "attesting_indices": [ - "1", - "2", - "3" - ], - "data": { - "beacon_block_root": "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20", - "index": "1", - "slot": "789", - "source": { - "epoch": "1", - "root": "0x0100000000000000000000000000000000000000000000000000000000000000" - }, - "target": { - "epoch": "2", - "root": "0x0100000000000000000000000000000000000000000000000000000000000000" - } - }, - "signature": "0x8c3095fd9d3a18e43ceeb7648281e16b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - }, - "attestation_2": { - "attesting_indices": [ - "1", - "2", - "3" - ], - "data": { - "beacon_block_root": "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20", - "index": "1", - "slot": "789", - "source": { - "epoch": "1", - "root": "0x0200000000000000000000000000000000000000000000000000000000000000" - }, - "target": { - "epoch": "2", - "root": "0x0200000000000000000000000000000000000000000000000000000000000000" - } - }, - "signature": "0x8c3095fd9d3a18e43ceeb7648281e16b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - } - } - ], - "blob_kzg_commitments": [ - "0x010203000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - ], - "bls_to_execution_changes": [ - { - "message": { - "from_bls_pubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "to_execution_address": "0x0000000000000000000000000000000000000000", - "validator_index": "1" - }, - "signature": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - } - ], - "deposits": [ - { - "data": { - "amount": "1", - "pubkey": "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2000000000000000000000000000000000", - "signature": "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "withdrawal_credentials": "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20" - }, - "proof": [ - "0x0101010101010101010101010101010101010101010101010101010101010101", - "0x0202020202020202020202020202020202020202020202020202020202020202", - "0x0303030303030303030303030303030303030303030303030303030303030303", - "0x0404040404040404040404040404040404040404040404040404040404040404", - "0x0505050505050505050505050505050505050505050505050505050505050505", - "0x0606060606060606060606060606060606060606060606060606060606060606", - "0x0707070707070707070707070707070707070707070707070707070707070707", - "0x0808080808080808080808080808080808080808080808080808080808080808", - "0x0909090909090909090909090909090909090909090909090909090909090909", - "0x0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a", - "0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", - "0x0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c", - "0x0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d", - "0x0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e", - "0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f", - "0x1010101010101010101010101010101010101010101010101010101010101010", - "0x1111111111111111111111111111111111111111111111111111111111111111", - "0x1212121212121212121212121212121212121212121212121212121212121212", - "0x1313131313131313131313131313131313131313131313131313131313131313", - "0x1414141414141414141414141414141414141414141414141414141414141414", - "0x1515151515151515151515151515151515151515151515151515151515151515", - "0x1616161616161616161616161616161616161616161616161616161616161616", - "0x1717171717171717171717171717171717171717171717171717171717171717", - "0x1818181818181818181818181818181818181818181818181818181818181818", - "0x1919191919191919191919191919191919191919191919191919191919191919", - "0x1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a", - "0x1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b", - "0x1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c", - "0x1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d", - "0x1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e", - "0x1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f", - "0x2020202020202020202020202020202020202020202020202020202020202020", - "0x2121212121212121212121212121212121212121212121212121212121212121" - ] - } - ], - "eth1_data": { - "block_hash": "0xd75a680056c50b4e339eda2f91ccd33bd75a680056c50b4e339eda2f91ccd33b", - "deposit_count": "216773", - "deposit_root": "0x0cacd599c9cdcee8398b40ef045baf2c00000000000000000000000000000000" - }, - "execution_payload_header": { - "base_fee_per_gas": "7", - "blob_gas_used": "0", - "block_hash": "0xb65b77e52407ff25000000000000000000000000000000000000000000000000", - "block_number": "220275", - "excess_blob_gas": "100", - "extra_data": "0x74657374", - "fee_recipient": "0xf97e180c050e5ab0000000000000000000000000", - "gas_limit": "30000000", - "gas_used": "84000", - "logs_bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "parent_hash": "0x98b62322edaa4d91000000000000000000000000000000000000000000000000", - "prev_randao": "0x83612b3de54001f7000000000000000000000000000000000000000000000000", - "receipts_root": "0x04deb4be6955e1a3000000000000000000000000000000000000000000000000", - "state_root": "0x3b6b594d5cbe7ff4000000000000000000000000000000000000000000000000", - "timestamp": "1732296378", - "transactions_root": "0xb1fcd304d8ba402b000000000000000000000000000000000000000000000000", - "withdrawals_root": "0x792930bbd5baac43000000000000000000000000000000000000000000000000" - }, - "execution_requests": { - "consolidations": [ - { - "source_address": "0x0100000000000000000000000000000000000000", - "source_pubkey": "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2000000000000000000000000000000000", - "target_pubkey": "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2000000000000000000000000000000000" - } - ], - "deposits": [ - { - "amount": "32000000000", - "index": "0", - "pubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "signature": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "withdrawal_credentials": "0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20" - } - ], - "withdrawals": [ - { - "amount": "0", - "source_address": "0x0100000000000000000000000000000000000000", - "validator_pubkey": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - } - ] - }, - "graffiti": "0x6c69676874686f75736500000000000000000000000000000000000000000000", - "proposer_slashings": [ - { - "signed_header_1": { - "message": { - "body_root": "0x0000000000000000000000000000000000000000000000000000000000000000", - "parent_root": "0x0000000000000000000000000000000000000000000000000000000000000000", - "proposer_index": "456", - "slot": "123", - "state_root": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - "signature": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - }, - "signed_header_2": { - "message": { - "body_root": "0x0000000000000000000000000000000000000000000000000000000000000000", - "parent_root": "0x0000000000000000000000000000000000000000000000000000000000000000", - "proposer_index": "456", - "slot": "123", - "state_root": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - "signature": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - } - } - ], - "randao_reveal": "0xa7a74e03d8ef909abc75b9452d167e150000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "sync_aggregate": { - "sync_committee_bits": "0xff98b62322edaa4d9198b62322edaa4d9198b62322edaa4d91ff98b62322edaa4d9198b62322edaa4d9198b62322edaa4d912322edaa4d9198b62322edaa4d91", - "sync_committee_signature": "0x8c3095fd9d3a18e43ceeb7648281e16b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - }, - "voluntary_exits": [ - { - "message": { - "epoch": "123", - "validator_index": "0" - }, - "signature": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - } - ] - }, - "parent_root": "0x9a8eef2096477e645150fee1a2ce13190382179a0ea843f31173715a1a14e074", - "proposer_index": "4295", - "slot": "252288", - "state_root": "0x4c033e0b4a34c0eb8e0caba126fae3ed303a83254fe39f8daaa673125f4042cc" - }, - "signature": "0x8c3095fd9d3a18e43ceeb7648281e16b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" -} \ No newline at end of file From 95ff45937b0530ce087286ed215cb96c8ea4a797 Mon Sep 17 00:00:00 2001 From: eltitanb Date: Fri, 11 Jul 2025 19:02:15 +0100 Subject: [PATCH 06/12] remove builder events modules --- Cargo.lock | 11 - Cargo.toml | 2 +- bin/src/lib.rs | 2 +- config.example.toml | 5 +- crates/cli/src/docker_init.rs | 79 +---- crates/common/src/config/constants.rs | 7 - crates/common/src/config/module.rs | 7 - crates/common/src/config/pbs.rs | 10 +- crates/common/src/pbs/constants.rs | 1 - crates/common/src/pbs/event.rs | 142 -------- crates/common/src/pbs/mod.rs | 2 - crates/pbs/src/routes/get_header.rs | 6 +- crates/pbs/src/routes/register_validator.rs | 4 +- crates/pbs/src/routes/reload.rs | 5 +- crates/pbs/src/routes/status.rs | 5 +- crates/pbs/src/routes/submit_block.rs | 7 +- crates/pbs/src/service.rs | 4 +- crates/pbs/src/state.rs | 8 +- docs/docs/developing/custom-modules.md | 3 +- docs/docs/get_started/configuration.md | 368 +++++++++++--------- docs/docs/get_started/running/binary.md | 12 +- examples/builder_log/Cargo.toml | 12 - examples/builder_log/Dockerfile | 29 -- examples/builder_log/src/main.rs | 35 -- justfile | 1 - tests/src/utils.rs | 1 - 26 files changed, 227 insertions(+), 541 deletions(-) delete mode 100644 crates/common/src/pbs/event.rs delete mode 100644 examples/builder_log/Cargo.toml delete mode 100644 examples/builder_log/Dockerfile delete mode 100644 examples/builder_log/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index 5776cd44..1b1efeb8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1438,17 +1438,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "builder_log" -version = "0.8.0" -dependencies = [ - "async-trait", - "commit-boost", - "eyre", - "tokio", - "tracing", -] - [[package]] name = "bumpalo" version = "3.17.0" diff --git a/Cargo.toml b/Cargo.toml index bce5278c..59956e79 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["benches/*", "bin", "crates/*", "examples/builder_log", "examples/da_commit", "examples/status_api", "tests"] +members = ["benches/*", "bin", "crates/*", "examples/da_commit", "examples/status_api", "tests"] resolver = "2" [workspace.package] diff --git a/bin/src/lib.rs b/bin/src/lib.rs index 6f44c7f9..e4457d45 100644 --- a/bin/src/lib.rs +++ b/bin/src/lib.rs @@ -9,7 +9,7 @@ pub mod prelude { load_builder_module_config, load_commit_module_config, load_pbs_config, load_pbs_custom_config, LogsSettings, StartCommitModuleConfig, PBS_MODULE_NAME, }, - pbs::{BlsPublicKey, BlsSignature, BuilderEvent, BuilderEventClient, OnBuilderApiEvent}, + pbs::{BlsPublicKey, BlsSignature}, signer::EcdsaSignature, types::Chain, utils::{initialize_tracing_log, utcnow_ms, utcnow_ns, utcnow_sec, utcnow_us}, diff --git a/config.example.toml b/config.example.toml index af84fdce..8d056cb3 100644 --- a/config.example.toml +++ b/config.example.toml @@ -239,15 +239,14 @@ proxy_dir = "./proxies" # secrets_path = "./tests/data/proxy/secrets" # Commit-Boost can optionally run "modules" which extend the capabilities of the sidecar. -# Currently, two types of modules are supported: +# Currently, one type of module is currently supported: # - "commit": modules which request commitment signatures from the validator keys -# - "events": modules which callback to BuilderAPI events as triggered from the PBS modules, used e.g. for monitoring # If any "commit" module is present, then the [signer] section should also be configured # OPTIONAL [[modules]] # Unique ID of the module id = "DA_COMMIT" -# Type of the module. Supported values: commit, events +# Type of the module. Supported values: commit type = "commit" # Docker image of the module docker_image = "test_da_commit" diff --git a/crates/cli/src/docker_init.rs b/crates/cli/src/docker_init.rs index 7f418e97..91a500a3 100644 --- a/crates/cli/src/docker_init.rs +++ b/crates/cli/src/docker_init.rs @@ -6,16 +6,15 @@ use std::{ use cb_common::{ config::{ - CommitBoostConfig, LogsSettings, ModuleKind, SignerConfig, SignerType, BUILDER_PORT_ENV, - BUILDER_URLS_ENV, CHAIN_SPEC_ENV, CONFIG_DEFAULT, CONFIG_ENV, DIRK_CA_CERT_DEFAULT, - DIRK_CA_CERT_ENV, DIRK_CERT_DEFAULT, DIRK_CERT_ENV, DIRK_DIR_SECRETS_DEFAULT, - DIRK_DIR_SECRETS_ENV, DIRK_KEY_DEFAULT, DIRK_KEY_ENV, JWTS_ENV, LOGS_DIR_DEFAULT, - LOGS_DIR_ENV, METRICS_PORT_ENV, MODULE_ID_ENV, MODULE_JWT_ENV, PBS_ENDPOINT_ENV, - 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_ENDPOINT_ENV, SIGNER_KEYS_ENV, SIGNER_MODULE_NAME, - SIGNER_URL_ENV, + CommitBoostConfig, LogsSettings, ModuleKind, SignerConfig, SignerType, CHAIN_SPEC_ENV, + CONFIG_DEFAULT, CONFIG_ENV, DIRK_CA_CERT_DEFAULT, DIRK_CA_CERT_ENV, DIRK_CERT_DEFAULT, + DIRK_CERT_ENV, DIRK_DIR_SECRETS_DEFAULT, DIRK_DIR_SECRETS_ENV, DIRK_KEY_DEFAULT, + DIRK_KEY_ENV, JWTS_ENV, LOGS_DIR_DEFAULT, LOGS_DIR_ENV, METRICS_PORT_ENV, MODULE_ID_ENV, + MODULE_JWT_ENV, PBS_ENDPOINT_ENV, 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_ENDPOINT_ENV, SIGNER_KEYS_ENV, + SIGNER_MODULE_NAME, SIGNER_URL_ENV, }, pbs::{BUILDER_API_PATH, GET_STATUS_PATH}, signer::{ProxyStore, SignerLoader, DEFAULT_SIGNER_PORT}, @@ -81,9 +80,6 @@ pub async fn handle_docker_init(config_path: PathBuf, output_dir: PathBuf) -> Re format!("http://cb_signer:{signer_port}") }; - let builder_events_port = 30000; - let mut builder_events_modules = Vec::new(); - let mut warnings = Vec::new(); let needs_signer_module = cb_config.pbs.with_signer || @@ -185,58 +181,6 @@ pub async fn handle_docker_init(config_path: PathBuf, output_dir: PathBuf) -> Re ..Service::default() } } - // an event module just needs a port to listen on - ModuleKind::Events => { - let mut ports = vec![]; - builder_events_modules - .push(format!("http://{module_cid}:{builder_events_port}")); - - // module ids are assumed unique, so envs dont override each other - let mut module_envs = IndexMap::from([ - get_env_val(MODULE_ID_ENV, &module.id), - get_env_val(CONFIG_ENV, CONFIG_DEFAULT), - get_env_uval(BUILDER_PORT_ENV, builder_events_port), - ]); - - if let Some((key, val)) = chain_spec_env.clone() { - module_envs.insert(key, val); - } - if let Some(metrics_config) = &cb_config.metrics { - if metrics_config.enabled { - let host_endpoint = - SocketAddr::from((metrics_config.host, metrics_port)); - ports.push(format!("{}:{}", host_endpoint, metrics_port)); - warnings.push(format!( - "{} has an exported port on {}", - module_cid, metrics_port - )); - targets.push(format!("{host_endpoint}")); - let (key, val) = get_env_uval(METRICS_PORT_ENV, metrics_port as u64); - module_envs.insert(key, val); - - metrics_port += 1; - } - } - if log_to_file { - let (key, val) = get_env_val(LOGS_DIR_ENV, LOGS_DIR_DEFAULT); - module_envs.insert(key, val); - } - - // volumes - let mut module_volumes = vec![config_volume.clone()]; - module_volumes.extend(chain_spec_volume.clone()); - module_volumes.extend(get_log_volume(&cb_config.logs, &module.id)); - - Service { - container_name: Some(module_cid.clone()), - image: Some(module.docker_image), - ports: Ports::Short(ports), - volumes: module_volumes, - environment: Environment::KvPair(module_envs), - depends_on: DependsOnOptions::Simple(vec!["cb_pbs".to_owned()]), - ..Service::default() - } - } }; services.insert(module_cid, Some(module_service)); @@ -283,11 +227,6 @@ pub async fn handle_docker_init(config_path: PathBuf, output_dir: PathBuf) -> Re let (key, val) = get_env_val(LOGS_DIR_ENV, LOGS_DIR_DEFAULT); pbs_envs.insert(key, val); } - if !builder_events_modules.is_empty() { - let env = builder_events_modules.join(","); - let (k, v) = get_env_val(BUILDER_URLS_ENV, &env); - pbs_envs.insert(k, v); - } // inside the container expose on 0.0.0.0 let container_endpoint = diff --git a/crates/common/src/config/constants.rs b/crates/common/src/config/constants.rs index 8b07f732..51a949f0 100644 --- a/crates/common/src/config/constants.rs +++ b/crates/common/src/config/constants.rs @@ -19,9 +19,6 @@ pub const LOGS_DIR_DEFAULT: &str = "/var/logs/commit-boost"; pub const PBS_IMAGE_DEFAULT: &str = "ghcr.io/commit-boost/pbs:latest"; pub const PBS_MODULE_NAME: &str = "pbs"; -/// Urls the pbs modules should post events to (comma separated) -pub const BUILDER_URLS_ENV: &str = "CB_BUILDER_URLS"; - /// Where to receive BuilderAPI calls from beacon node pub const PBS_ENDPOINT_ENV: &str = "CB_PBS_ENDPOINT"; @@ -90,7 +87,3 @@ pub const MODULE_ID_ENV: &str = "CB_MODULE_ID"; pub const MODULE_JWT_ENV: &str = "CB_SIGNER_JWT"; /// Where to send signature request pub const SIGNER_URL_ENV: &str = "CB_SIGNER_URL"; - -/// Events modules -/// Where to receive builder events -pub const BUILDER_PORT_ENV: &str = "CB_BUILDER_PORT"; diff --git a/crates/common/src/config/module.rs b/crates/common/src/config/module.rs index 16b089ca..89758883 100644 --- a/crates/common/src/config/module.rs +++ b/crates/common/src/config/module.rs @@ -10,7 +10,6 @@ use crate::{ constants::{CONFIG_ENV, MODULE_ID_ENV, MODULE_JWT_ENV, SIGNER_URL_ENV}, load_env_var, utils::load_file_from_env, - BUILDER_PORT_ENV, }, types::{Chain, Jwt, ModuleId}, }; @@ -19,8 +18,6 @@ use crate::{ pub enum ModuleKind { #[serde(alias = "commit")] Commit, - #[serde(alias = "events")] - Events, } /// Static module config from config file @@ -120,8 +117,6 @@ pub struct StartBuilderModuleConfig { pub id: ModuleId, /// Chain spec pub chain: Chain, - /// Where to listen for Builder events - pub server_port: u16, /// Opaque module config pub extra: T, } @@ -129,7 +124,6 @@ pub struct StartBuilderModuleConfig { pub fn load_builder_module_config() -> eyre::Result> { let module_id = ModuleId(load_env_var(MODULE_ID_ENV)?); - let builder_events_port: u16 = load_env_var(BUILDER_PORT_ENV)?.parse()?; #[derive(Debug, Deserialize)] struct ThisModuleConfig { @@ -176,7 +170,6 @@ pub fn load_builder_module_config() -> eyre::Result, /// Signer client to call Signer API pub signer_client: Option, - /// Event publisher - pub event_publisher: Option, /// Muxes config pub muxes: Option>, } @@ -245,7 +243,6 @@ pub async fn load_pbs_config() -> Result { let relay_clients = config.relays.into_iter().map(RelayClient::new).collect::>>()?; - let maybe_publiher = BuilderEventPublisher::new_from_env()?; let mut all_relays = HashMap::with_capacity(relay_clients.len()); if let Some(muxes) = &muxes { @@ -273,7 +270,6 @@ pub async fn load_pbs_config() -> Result { relays: relay_clients, all_relays, signer_client: None, - event_publisher: maybe_publiher, muxes, }) } @@ -321,7 +317,6 @@ pub async fn load_pbs_custom_config() -> Result<(PbsModuleC let relay_clients = cb_config.relays.into_iter().map(RelayClient::new).collect::>>()?; - let maybe_publiher = BuilderEventPublisher::new_from_env()?; let mut all_relays = HashMap::with_capacity(relay_clients.len()); if let Some(muxes) = &muxes { @@ -363,7 +358,6 @@ pub async fn load_pbs_custom_config() -> Result<(PbsModuleC relays: relay_clients, all_relays, signer_client, - event_publisher: maybe_publiher, muxes, }, cb_config.pbs.extra, diff --git a/crates/common/src/pbs/constants.rs b/crates/common/src/pbs/constants.rs index 314915ce..4713e5d4 100644 --- a/crates/common/src/pbs/constants.rs +++ b/crates/common/src/pbs/constants.rs @@ -16,7 +16,6 @@ pub const HEADER_VERSION_KEY: &str = "X-CommitBoost-Version"; pub const HEADER_VERSION_VALUE: &str = COMMIT_BOOST_VERSION; pub const HEADER_START_TIME_UNIX_MS: &str = "Date-Milliseconds"; -pub const BUILDER_EVENTS_PATH: &str = "/builder_events"; pub const DEFAULT_PBS_JWT_KEY: &str = "DEFAULT_PBS"; pub const DEFAULT_PBS_PORT: u16 = 18550; diff --git a/crates/common/src/pbs/event.rs b/crates/common/src/pbs/event.rs deleted file mode 100644 index 98276d14..00000000 --- a/crates/common/src/pbs/event.rs +++ /dev/null @@ -1,142 +0,0 @@ -use std::{net::SocketAddr, time::Duration}; - -use alloy::{primitives::B256, rpc::types::beacon::relay::ValidatorRegistration}; -use async_trait::async_trait; -use axum::{ - extract::State, - response::{IntoResponse, Response}, - routing::post, - Json, -}; -use eyre::{bail, Result}; -use reqwest::StatusCode; -use serde::{Deserialize, Serialize}; -use tokio::net::TcpListener; -use tracing::{error, info, trace, warn}; -use url::Url; - -use super::{ - GetHeaderParams, GetHeaderResponse, SignedBlindedBeaconBlock, SubmitBlindedBlockResponse, -}; -use crate::{ - config::{load_optional_env_var, BUILDER_URLS_ENV, HTTP_TIMEOUT_SECONDS_DEFAULT}, - pbs::BUILDER_EVENTS_PATH, -}; - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub enum BuilderEvent { - GetHeaderRequest(GetHeaderParams), - GetHeaderResponse(Box>), - GetStatusEvent, - GetStatusResponse, - SubmitBlockRequest(Box), - SubmitBlockResponse(Box), - MissedPayload { - /// Hash for the block for which no payload was received - block_hash: B256, - }, - RegisterValidatorRequest(Vec), - RegisterValidatorResponse, - ReloadEvent, - ReloadResponse, -} - -#[derive(Debug, Clone)] -pub struct BuilderEventPublisher { - client: reqwest::Client, - endpoints: Vec, -} - -impl BuilderEventPublisher { - pub fn new(endpoints: Vec, http_timeout: Duration) -> Result { - for endpoint in &endpoints { - if endpoint.scheme() != "https" { - warn!("BuilderEventPublisher endpoint {endpoint} is insecure, consider using HTTPS if possible instead"); - } - } - Ok(Self { client: reqwest::ClientBuilder::new().timeout(http_timeout).build()?, endpoints }) - } - - pub fn new_from_env() -> Result> { - let http_timeout = Duration::from_secs(HTTP_TIMEOUT_SECONDS_DEFAULT); - - load_optional_env_var(BUILDER_URLS_ENV) - .map(|joined| { - let endpoints = joined - .trim() - .split(',') - .map(|base| { - let url = base.trim().parse::()?.join(BUILDER_EVENTS_PATH)?; - Ok(url) - }) - .collect::>>()?; - - Self::new(endpoints, http_timeout) - }) - .transpose() - } - - pub fn publish(&self, event: BuilderEvent) { - for endpoint in self.endpoints.clone() { - let client = self.client.clone(); - let event = event.clone(); - - tokio::spawn(async move { - trace!("Sending events to {}", endpoint); - if let Err(err) = client - .post(endpoint) - .json(&event) - .send() - .await - .and_then(|res| res.error_for_status()) - { - error!("Failed to publish event: {:?}", err) - }; - }); - } - } - - pub fn n_subscribers(&self) -> usize { - self.endpoints.len() - } -} - -pub struct BuilderEventClient { - pub port: u16, - pub processor: T, -} - -impl BuilderEventClient { - pub fn new(port: u16, processor: T) -> Self { - Self { port, processor } - } - - pub async fn run(self) -> eyre::Result<()> { - info!("Starting builder events server on port {}", self.port); - - let router = axum::Router::new() - .route(BUILDER_EVENTS_PATH, post(handle_builder_event::)) - .with_state(self.processor); - let address = SocketAddr::from(([0, 0, 0, 0], self.port)); - let listener = TcpListener::bind(&address).await?; - - axum::serve(listener, router).await?; - - bail!("Builder events stopped") - } -} - -async fn handle_builder_event( - State(processor): State, - Json(event): Json, -) -> Response { - trace!("Handling builder event"); - processor.on_builder_api_event(event).await; - StatusCode::OK.into_response() -} - -#[async_trait] -/// This is what modules are expected to implement to process BuilderApi events -pub trait OnBuilderApiEvent { - async fn on_builder_api_event(&self, event: BuilderEvent); -} diff --git a/crates/common/src/pbs/mod.rs b/crates/common/src/pbs/mod.rs index 05f4f77b..7a831dd1 100644 --- a/crates/common/src/pbs/mod.rs +++ b/crates/common/src/pbs/mod.rs @@ -1,10 +1,8 @@ mod constants; pub mod error; -mod event; mod relay; mod types; pub use constants::*; -pub use event::*; pub use relay::*; pub use types::*; diff --git a/crates/pbs/src/routes/get_header.rs b/crates/pbs/src/routes/get_header.rs index 53aa194d..77607c28 100644 --- a/crates/pbs/src/routes/get_header.rs +++ b/crates/pbs/src/routes/get_header.rs @@ -5,7 +5,7 @@ use axum::{ response::IntoResponse, }; use cb_common::{ - pbs::{BuilderEvent, GetHeaderParams}, + pbs::GetHeaderParams, utils::{get_user_agent, ms_into_slot}, }; use reqwest::StatusCode; @@ -30,8 +30,6 @@ pub async fn handle_get_header>( let state = state.read().clone(); - state.publish_event(BuilderEvent::GetHeaderRequest(params.clone())); - let ua = get_user_agent(&req_headers); let ms_into_slot = ms_into_slot(params.slot, state.config.chain); @@ -39,8 +37,6 @@ pub async fn handle_get_header>( match A::get_header(params, req_headers, state.clone()).await { Ok(res) => { - state.publish_event(BuilderEvent::GetHeaderResponse(Box::new(res.clone()))); - if let Some(max_bid) = res { info!(value_eth = format_ether(max_bid.value()), block_hash =% max_bid.block_hash(), "received header"); diff --git a/crates/pbs/src/routes/register_validator.rs b/crates/pbs/src/routes/register_validator.rs index 93c84c3f..acb0168a 100644 --- a/crates/pbs/src/routes/register_validator.rs +++ b/crates/pbs/src/routes/register_validator.rs @@ -1,6 +1,6 @@ use alloy::rpc::types::beacon::relay::ValidatorRegistration; use axum::{extract::State, http::HeaderMap, response::IntoResponse, Json}; -use cb_common::{pbs::BuilderEvent, utils::get_user_agent}; +use cb_common::utils::get_user_agent; use reqwest::StatusCode; use tracing::{error, info, trace}; @@ -20,14 +20,12 @@ pub async fn handle_register_validator>( let state = state.read().clone(); trace!(?registrations); - state.publish_event(BuilderEvent::RegisterValidatorRequest(registrations.clone())); let ua = get_user_agent(&req_headers); info!(ua, num_registrations = registrations.len(), "new request"); if let Err(err) = A::register_validator(registrations, req_headers, state.clone()).await { - state.publish_event(BuilderEvent::RegisterValidatorResponse); error!(%err, "all relays failed registration"); let err = PbsClientError::NoResponse; diff --git a/crates/pbs/src/routes/reload.rs b/crates/pbs/src/routes/reload.rs index 5326c726..5ba33329 100644 --- a/crates/pbs/src/routes/reload.rs +++ b/crates/pbs/src/routes/reload.rs @@ -1,5 +1,5 @@ use axum::{extract::State, http::HeaderMap, response::IntoResponse}; -use cb_common::{pbs::BuilderEvent, utils::get_user_agent}; +use cb_common::utils::get_user_agent; use reqwest::StatusCode; use tracing::{error, info}; @@ -16,15 +16,12 @@ pub async fn handle_reload>( ) -> Result { let prev_state = state.read().clone(); - prev_state.publish_event(BuilderEvent::ReloadEvent); - let ua = get_user_agent(&req_headers); info!(ua, relay_check = prev_state.config.pbs_config.relay_check); match A::reload(prev_state.clone()).await { Ok(new_state) => { - prev_state.publish_event(BuilderEvent::ReloadResponse); info!("config reload successful"); *state.write() = new_state; diff --git a/crates/pbs/src/routes/status.rs b/crates/pbs/src/routes/status.rs index b8cf3408..d0f68ac7 100644 --- a/crates/pbs/src/routes/status.rs +++ b/crates/pbs/src/routes/status.rs @@ -1,5 +1,5 @@ use axum::{extract::State, http::HeaderMap, response::IntoResponse}; -use cb_common::{pbs::BuilderEvent, utils::get_user_agent}; +use cb_common::utils::get_user_agent; use reqwest::StatusCode; use tracing::{error, info}; @@ -17,15 +17,12 @@ pub async fn handle_get_status>( ) -> Result { let state = state.read().clone(); - state.publish_event(BuilderEvent::GetStatusEvent); - let ua = get_user_agent(&req_headers); info!(ua, relay_check = state.config.pbs_config.relay_check, "new request"); match A::get_status(req_headers, state.clone()).await { Ok(_) => { - state.publish_event(BuilderEvent::GetStatusResponse); info!("relay check successful"); BEACON_NODE_STATUS.with_label_values(&["200", STATUS_ENDPOINT_TAG]).inc(); diff --git a/crates/pbs/src/routes/submit_block.rs b/crates/pbs/src/routes/submit_block.rs index 0124a826..9b2da0d6 100644 --- a/crates/pbs/src/routes/submit_block.rs +++ b/crates/pbs/src/routes/submit_block.rs @@ -1,6 +1,6 @@ use axum::{extract::State, http::HeaderMap, response::IntoResponse, Json}; use cb_common::{ - pbs::{BuilderEvent, SignedBlindedBeaconBlock}, + pbs::SignedBlindedBeaconBlock, utils::{get_user_agent, timestamp_of_slot_start_millis, utcnow_ms}, }; use reqwest::StatusCode; @@ -28,8 +28,6 @@ pub async fn handle_submit_block>( let state = state.read().clone(); - state.publish_event(BuilderEvent::SubmitBlockRequest(Box::new(signed_blinded_block.clone()))); - let now = utcnow_ms(); let slot = signed_blinded_block.slot(); let block_hash = signed_blinded_block.block_hash(); @@ -41,7 +39,7 @@ pub async fn handle_submit_block>( match A::submit_block(signed_blinded_block, req_headers, state.clone()).await { Ok(res) => { trace!(?res); - state.publish_event(BuilderEvent::SubmitBlockResponse(Box::new(res.clone()))); + info!("received unblinded block"); BEACON_NODE_STATUS.with_label_values(&["200", SUBMIT_BLINDED_BLOCK_ENDPOINT_TAG]).inc(); @@ -50,7 +48,6 @@ pub async fn handle_submit_block>( Err(err) => { error!(%err, %block_hash, "CRITICAL: no payload received from relays. Check previous logs or use the Relay Data API"); - state.publish_event(BuilderEvent::MissedPayload { block_hash }); let err = PbsClientError::NoPayload; BEACON_NODE_STATUS diff --git a/crates/pbs/src/service.rs b/crates/pbs/src/service.rs index ce8162e4..db3abd1b 100644 --- a/crates/pbs/src/service.rs +++ b/crates/pbs/src/service.rs @@ -25,9 +25,7 @@ pub struct PbsService; impl PbsService { pub async fn run>(state: PbsState) -> Result<()> { let addr = state.config.endpoint; - let events_subs = - state.config.event_publisher.as_ref().map(|e| e.n_subscribers()).unwrap_or_default(); - info!(version = COMMIT_BOOST_VERSION, commit_hash = COMMIT_BOOST_COMMIT, ?addr, events_subs, chain =? state.config.chain, "starting PBS service"); + info!(version = COMMIT_BOOST_VERSION, commit_hash = COMMIT_BOOST_COMMIT, ?addr, chain =? state.config.chain, "starting PBS service"); let app = create_app_router::(RwLock::new(state).into()); let listener = TcpListener::bind(addr).await?; diff --git a/crates/pbs/src/state.rs b/crates/pbs/src/state.rs index 3381af9d..19d53729 100644 --- a/crates/pbs/src/state.rs +++ b/crates/pbs/src/state.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use cb_common::{ config::{PbsConfig, PbsModuleConfig}, - pbs::{BlsPublicKey, BuilderEvent, RelayClient}, + pbs::{BlsPublicKey, RelayClient}, }; use parking_lot::RwLock; @@ -36,12 +36,6 @@ impl PbsState where S: BuilderApiState, { - pub fn publish_event(&self, e: BuilderEvent) { - if let Some(publisher) = self.config.event_publisher.as_ref() { - publisher.publish(e); - } - } - // Getters pub fn pbs_config(&self) -> &PbsConfig { &self.config.pbs_config diff --git a/docs/docs/developing/custom-modules.md b/docs/docs/developing/custom-modules.md index 7282db70..9d73b260 100644 --- a/docs/docs/developing/custom-modules.md +++ b/docs/docs/developing/custom-modules.md @@ -1,11 +1,12 @@ --- sidebar_position: 1 --- + # Custom Modules + Commit-Boost aims to provide an open platform for developers to create and distribute commitment protocols sidecars. There are three ways to leverage Commit-Boost modularity: 1. Commit Modules, which request signatures from the proposer, e.g. for preconfirmations ([example](https://github.com/Commit-Boost/commit-boost-client/tree/78bdc47bf89082f4d1ea302f9a3f86f609966b28/examples/da_commit)). 2. PBS Modules, which tweak the default PBS Module with additional logic, e.g. verifying additional constraints in `get_header` ([example](https://github.com/Commit-Boost/commit-boost-client/tree/78bdc47bf89082f4d1ea302f9a3f86f609966b28/examples/status_api)). -3. PBS Events, which trigger based on the different events of the PBS lifecycle and can be used e.g. for monitoring and reporting ([example](https://github.com/Commit-Boost/commit-boost-client/tree/78bdc47bf89082f4d1ea302f9a3f86f609966b28/examples/builder_log)). diff --git a/docs/docs/get_started/configuration.md b/docs/docs/get_started/configuration.md index 5dd46329..ff6f3b42 100644 --- a/docs/docs/get_started/configuration.md +++ b/docs/docs/get_started/configuration.md @@ -10,6 +10,7 @@ Commit-Boost needs a configuration file detailing all the services that you want - For some additional examples on config presets, check out [here](https://github.com/Commit-Boost/commit-boost-client/tree/main/configs). ## Minimal PBS setup on Holesky + ```toml chain = "Holesky" @@ -57,122 +58,134 @@ We currently support Lighthouse, Prysm, Teku and Lodestar's keystores so it's ea
Lighthouse - #### File structure: - ``` - ├── keys - │   ├── - │   │   └── voting-keystore.json - │   └── - │   └── voting-keystore.json - └── secrets -    ├── -    └── - ``` - - #### Config: - ```toml - [pbs] - ... - with_signer = true - - [signer] - port = 20000 - - [signer.local.loader] - format = "lighthouse" - keys_path = "keys" - secrets_path = "secrets" - ``` +#### File structure: + +``` +├── keys +│   ├── +│   │   └── voting-keystore.json +│   └── +│   └── voting-keystore.json +└── secrets +    ├── +    └── +``` + +#### Config: + +```toml +[pbs] +... +with_signer = true + +[signer] +port = 20000 + +[signer.local.loader] +format = "lighthouse" +keys_path = "keys" +secrets_path = "secrets" +``` +
Prysm - #### File structure: - ``` - ├── wallet - │   └── direct - │      └── accounts - │         └──all-accounts.keystore.json - └── secrets -    └── password.txt - ``` - - #### Config: - ```toml - [pbs] - ... - with_signer = true - - [signer] - port = 20000 - - [signer.local.loader] - format = "prysm" - keys_path = "wallet/direct/accounts/all-accounts.keystore.json" - secrets_path = "secrets/password.txt" - ``` +#### File structure: + +``` +├── wallet +│   └── direct +│      └── accounts +│         └──all-accounts.keystore.json +└── secrets +    └── password.txt +``` + +#### Config: + +```toml +[pbs] +... +with_signer = true + +[signer] +port = 20000 + +[signer.local.loader] +format = "prysm" +keys_path = "wallet/direct/accounts/all-accounts.keystore.json" +secrets_path = "secrets/password.txt" +``` +
Teku - #### File structure: - ``` - ├── keys - │   ├── .json - │   └── .json - └── secrets -    ├── .txt -    └── .txt - ``` - - #### Config: - ```toml - [pbs] - ... - with_signer = true - - [signer] - port = 20000 - - [signer.local.loader] - format = "teku" - keys_path = "keys" - secrets_path = "secrets" - ``` +#### File structure: + +``` +├── keys +│   ├── .json +│   └── .json +└── secrets +    ├── .txt +    └── .txt +``` + +#### Config: + +```toml +[pbs] +... +with_signer = true + +[signer] +port = 20000 + +[signer.local.loader] +format = "teku" +keys_path = "keys" +secrets_path = "secrets" +``` +
Lodestar - #### File structure: - ``` - ├── keys - │   ├── .json - │   └── .json - └── secrets -    └── password.txt - ``` - - #### Config: - ```toml - [pbs] - ... - with_signer = true - - [signer] - port = 20000 - - [signer.local.loader] - format = "lodestar" - keys_path = "keys" - secrets_path = "secrets/password.txt" - ``` - - :::note - All keys have the same password stored in `secrets/password.txt` - ::: +#### File structure: + +``` +├── keys +│   ├── .json +│   └── .json +└── secrets +    └── password.txt +``` + +#### Config: + +```toml +[pbs] +... +with_signer = true + +[signer] +port = 20000 + +[signer.local.loader] +format = "lodestar" +keys_path = "keys" +secrets_path = "secrets/password.txt" +``` + +:::note +All keys have the same password stored in `secrets/password.txt` +::: +
### Proxy keys store @@ -184,78 +197,81 @@ To persist proxy keys across restarts, you must enable the proxy store in the co
File - The keys are stored in plain text in a file. This method is unsafe and should only be used for testing. - - #### File structure - - ``` - - └── - └── bls - ├── - └── - ``` - - #### Configuration - - ```toml - [signer.local.store] - proxy_dir = "path/to/proxy_dir" - ``` - - Where each `` file contains the following: - ```json - { - "secret": "0x...", - "delegation": { - "message": { - "delegator": "0x...", - "proxy": "0x..." - }, - "signature": "0x..." - } +The keys are stored in plain text in a file. This method is unsafe and should only be used for testing. + +#### File structure + +``` + +└── + └── bls + ├── + └── +``` + +#### Configuration + +```toml +[signer.local.store] +proxy_dir = "path/to/proxy_dir" +``` + +Where each `` file contains the following: + +```json +{ + "secret": "0x...", + "delegation": { + "message": { + "delegator": "0x...", + "proxy": "0x..." + }, + "signature": "0x..." } - ``` +} +``` +
ERC2335 - The keys are stored in a ERC-2335 style keystore, along with a password. This way, you can safely share the keys directory as without the password they are useless. - - #### File structure - - ``` - ├── - │ └── - │ └── - │ ├── bls/ - │ │ ├── .json - │ │ ├── .sig - │ │ ├── .json - │ │ └── .sig - │ └── ecdsa/ - │ ├── .json - │ └── .sig - └── - └── - └── - ├── bls/ - │ ├── - │ └── - └── ecdsa - └── - ``` - - #### Configuration - - ```toml - [signer.local.store] - keys_path = "path/to/keys" - secrets_path = "path/to/secrets" - ``` - - Where the `.json` files contain ERC-2335 keystore, the `.sig` files contain the signature of the delegation, and `` files contain the password to decrypt the keystores. +The keys are stored in a ERC-2335 style keystore, along with a password. This way, you can safely share the keys directory as without the password they are useless. + +#### File structure + +``` +├── +│ └── +│ └── +│ ├── bls/ +│ │ ├── .json +│ │ ├── .sig +│ │ ├── .json +│ │ └── .sig +│ └── ecdsa/ +│ ├── .json +│ └── .sig +└── + └── + └── + ├── bls/ + │ ├── + │ └── + └── ecdsa + └── +``` + +#### Configuration + +```toml +[signer.local.store] +keys_path = "path/to/keys" +secrets_path = "path/to/secrets" +``` + +Where the `.json` files contain ERC-2335 keystore, the `.sig` files contain the signature of the delegation, and `` files contain the password to decrypt the keystores. +
### Remote signer @@ -311,17 +327,21 @@ Delegation signatures will be stored in files with the format `/deleg A full example of a config file with Dirk can be found [here](https://github.com/Commit-Boost/commit-boost-client/blob/main/examples/configs/dirk_signer.toml). ## Custom module + We currently provide a test module that needs to be built locally. To build the module run: + ```bash just docker-build-test-modules ``` + :::note We use `just` as command runner. If you don't have it installed, either install it from https://github.com/casey/just or run the commands manually from the `justfile` at the root of the repo. ::: -This will create a Docker image called `test_da_commit` that periodically requests signatures from the validator, and a `test_builder_log` module that logs BuilderAPI events. +This will create a Docker image called `test_da_commit` that periodically requests signatures from the validator. The `cb-config.toml` file needs to be updated as follows: + ```toml [pbs] port = 18550 @@ -345,32 +365,32 @@ id = "DA_COMMIT" type = "commit" docker_image = "test_da_commit" sleep_secs = 5 - -[[modules]] -id = "BUILDER_LOG" -type = "events" -docker_image = "test_builder_log" ``` A few things to note: + - We now added a `signer` section which will be used to create the Signer module. - There is now a `[[modules]]` section which at a minimum needs to specify the module `id`, `type` and `docker_image`. Additional parameters needed for the business logic of the module will also be here, To learn more about developing modules, check out [here](/category/developing). ## Vouch + [Vouch](https://github.com/attestantio/vouch) is a multi-node validator client built by [Attestant](https://www.attestant.io/). Vouch is particular in that it also integrates an MEV-Boost client to interact with relays. The Commit-Boost PBS module is compatible with the Vouch `blockrelay` since it implements the same Builder-API as relays. For example, depending on your setup and preference, you may want to fetch headers from a given relay using Commit-Boost vs using the built-in Vouch `blockrelay`. ### Configuration + Get familiar on how to set up Vouch [here](https://github.com/attestantio/vouch/blob/master/docs/getting_started.md). You can setup Commit-Boost with Vouch in two ways. For simplicity, assume that in Vouch `blockrelay.listen-address: 127.0.0.0:19550` and in Commit-Boost `pbs.port = 18550`. #### Beacon Node to Vouch + In this setup, the BN Builder-API endpoint will be pointing to the Vouch `blockrelay` (e.g. for Lighthouse you will need the flag `--builder=http://127.0.0.0:19550`). Modify the `blockrelay.config` file to add Commit-Boost: + ```json "relays": { "http://127.0.0.0:18550": {} @@ -378,6 +398,7 @@ Modify the `blockrelay.config` file to add Commit-Boost: ``` #### Beacon Node to Commit-Boost + In this setup, the BN Builder-API endpoint will be pointing to the PBS module (e.g. for Lighthouse you will need the flag `--builder=http://127.0.0.0:18550`). This will bypass the `blockrelay` entirely so make sure all relays are properly configured in the `[[relays]]` section. @@ -387,6 +408,7 @@ This approach could also work if you have a multi-beacon-node setup, where some ::: ### Notes + - It's up to you to decide which relays will be connected via Commit-Boost (`[[relays]]` section in the `toml` config) and which via Vouch (additional entries in the `relays` field). Remember that any rate-limit will be shared across the two sidecars, if running on the same machine. - You may occasionally see a `timeout` error during registrations, especially if you're running a large number of validators in the same instance. This can resolve itself as registrations will be cleared later in the epoch when relays are less busy processing other registrations. Alternatively you can also adjust the `builderclient.timeout` option in `.vouch.yml`. diff --git a/docs/docs/get_started/running/binary.md b/docs/docs/get_started/running/binary.md index 385e7a0c..10815d6e 100644 --- a/docs/docs/get_started/running/binary.md +++ b/docs/docs/get_started/running/binary.md @@ -8,24 +8,26 @@ description: Run Commit-Boost modules natively Running the modules natively means you opt out of the security guarantees made by Docker and it's up to you how to setup and ensure the modules run safely. ::: - ## Setup + Get the binary of the module either by compiling from source or by downloading a [published release](https://github.com/Commit-Boost/commit-boost-client/releases). Modules need some environment variables to work correctly. ### Common + - `CB_CONFIG`: required, path to the `.toml` config file. - `CHAIN_SPEC_ENV`: optional, path to a chain spec file. This will override the `[chain]` field in the `.toml` config. - `CB_METRICS_PORT`: optional, port where to expose the `/metrics` endpoint for Prometheus. - `CB_LOGS_DIR`: optional, directory to store logs. This will override the directory in the `.toml` config. ### PBS Module -- `CB_BUILDER_URLS`: optional, comma-separated list of urls to `events` modules where to post builder events. + - `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_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). @@ -40,15 +42,14 @@ Modules need some environment variables to work correctly. - `CB_SIGNER_DIRK_CA_CERT_FILE`: optional, path to the CA certificate file. ### Modules + - `CB_MODULE_ID`: required, unique id of the module. #### Commit modules + - `CB_SIGNER_URL`: required, url to the signer module server. - `CB_SIGNER_JWT`: required, jwt to use for signature requests. -#### Events modules -- `CB_BUILDER_PORT`: required, port to open to receive builder events from the PBS module. - Modules might also have additional envs required, which should be detailed by the maintainers. ## Start @@ -60,4 +61,5 @@ CB_CONFIG=./cb-config.toml commit-boost-pbs ``` ## Security + Running the modules natively means you opt out of the security guarantees made by Docker and it's up to you how to setup and ensure the modules run safely. diff --git a/examples/builder_log/Cargo.toml b/examples/builder_log/Cargo.toml deleted file mode 100644 index 64173a5f..00000000 --- a/examples/builder_log/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -edition.workspace = true -name = "builder_log" -rust-version.workspace = true -version.workspace = true - -[dependencies] -async-trait.workspace = true -commit-boost = { path = "../../bin" } -eyre.workspace = true -tokio.workspace = true -tracing.workspace = true diff --git a/examples/builder_log/Dockerfile b/examples/builder_log/Dockerfile deleted file mode 100644 index c0fd69b4..00000000 --- a/examples/builder_log/Dockerfile +++ /dev/null @@ -1,29 +0,0 @@ -FROM lukemathwalker/cargo-chef:latest-rust-1 AS chef -WORKDIR /app - -FROM chef AS planner -COPY . . -RUN cargo chef prepare --recipe-path recipe.json - -FROM chef AS builder -COPY --from=planner /app/recipe.json recipe.json - -RUN cargo chef cook --release --recipe-path recipe.json - -RUN apt-get update && apt-get install -y protobuf-compiler - -COPY . . -RUN cargo build --release --bin builder_log - - -FROM ubuntu AS runtime -WORKDIR /app - -RUN apt-get update -RUN apt-get install -y openssl ca-certificates libssl3 libssl-dev - -COPY --from=builder /app/target/release/builder_log /usr/local/bin -ENTRYPOINT ["/usr/local/bin/builder_log"] - - - diff --git a/examples/builder_log/src/main.rs b/examples/builder_log/src/main.rs deleted file mode 100644 index a40df63d..00000000 --- a/examples/builder_log/src/main.rs +++ /dev/null @@ -1,35 +0,0 @@ -use async_trait::async_trait; -use commit_boost::prelude::*; -use tracing::{error, info}; - -#[derive(Debug, Clone)] -struct LogProcessor; - -#[async_trait] -impl OnBuilderApiEvent for LogProcessor { - async fn on_builder_api_event(&self, event: BuilderEvent) { - info!(?event, "Received builder event"); - } -} - -#[tokio::main] -async fn main() -> eyre::Result<()> { - match load_builder_module_config::<()>() { - Ok(config) => { - let _guard = initialize_tracing_log(&config.id, LogsSettings::from_env_config()?); - - info!(module_id = %config.id, "Starting module"); - - let client = BuilderEventClient::new(config.server_port, LogProcessor); - - if let Err(err) = client.run().await { - error!(%err, "Service failed"); - } - } - Err(err) => { - eprintln!("Failed to load module config: {err:?}"); - } - } - - Ok(()) -} diff --git a/justfile b/justfile index 5263aaa1..cc864823 100644 --- a/justfile +++ b/justfile @@ -184,7 +184,6 @@ install-protoc: docker-build-test-modules: docker build -t test_da_commit . -f examples/da_commit/Dockerfile - docker build -t test_builder_log . -f examples/builder_log/Dockerfile docker build -t test_status_api . -f examples/status_api/Dockerfile # Cleans the build directory, removing all built binaries. diff --git a/tests/src/utils.rs b/tests/src/utils.rs index 28d1a82b..85ede465 100644 --- a/tests/src/utils.rs +++ b/tests/src/utils.rs @@ -96,7 +96,6 @@ pub fn to_pbs_config( endpoint: SocketAddr::new(pbs_config.host.into(), pbs_config.port), pbs_config: Arc::new(pbs_config), signer_client: None, - event_publisher: None, all_relays: relays.clone(), relays, muxes: None, From f383f6fbdea8633cc514270431cad253f7c91427 Mon Sep 17 00:00:00 2001 From: eltitanb Date: Thu, 24 Jul 2025 20:38:35 +0100 Subject: [PATCH 07/12] comments --- config.example.toml | 2 +- docs/docs/developing/custom-modules.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config.example.toml b/config.example.toml index 8d056cb3..b40c07f5 100644 --- a/config.example.toml +++ b/config.example.toml @@ -239,7 +239,7 @@ proxy_dir = "./proxies" # secrets_path = "./tests/data/proxy/secrets" # Commit-Boost can optionally run "modules" which extend the capabilities of the sidecar. -# Currently, one type of module is currently supported: +# Currently, one type of module is supported: # - "commit": modules which request commitment signatures from the validator keys # If any "commit" module is present, then the [signer] section should also be configured # OPTIONAL diff --git a/docs/docs/developing/custom-modules.md b/docs/docs/developing/custom-modules.md index 9d73b260..cf224448 100644 --- a/docs/docs/developing/custom-modules.md +++ b/docs/docs/developing/custom-modules.md @@ -6,7 +6,7 @@ sidebar_position: 1 Commit-Boost aims to provide an open platform for developers to create and distribute commitment protocols sidecars. -There are three ways to leverage Commit-Boost modularity: +There are two ways to leverage Commit-Boost modularity: 1. Commit Modules, which request signatures from the proposer, e.g. for preconfirmations ([example](https://github.com/Commit-Boost/commit-boost-client/tree/78bdc47bf89082f4d1ea302f9a3f86f609966b28/examples/da_commit)). 2. PBS Modules, which tweak the default PBS Module with additional logic, e.g. verifying additional constraints in `get_header` ([example](https://github.com/Commit-Boost/commit-boost-client/tree/78bdc47bf89082f4d1ea302f9a3f86f609966b28/examples/status_api)). From 828302dec1fffde299f132d19c126f35d3dd5e1f Mon Sep 17 00:00:00 2001 From: eltitanb Date: Sun, 27 Jul 2025 22:51:06 +0100 Subject: [PATCH 08/12] refactor BLS constant bytes --- crates/common/src/config/mux.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/crates/common/src/config/mux.rs b/crates/common/src/config/mux.rs index 51e84495..fe027a90 100644 --- a/crates/common/src/config/mux.rs +++ b/crates/common/src/config/mux.rs @@ -8,7 +8,7 @@ use std::{ use alloy::{ primitives::{address, Address, U256}, providers::ProviderBuilder, - rpc::client::RpcClient, + rpc::{client::RpcClient, types::beacon::constants::BLS_PUBLIC_KEY_BYTES_LEN}, sol, transports::http::Http, }; @@ -286,7 +286,6 @@ async fn fetch_lido_registry_keys( debug!("fetching {total_keys} total keys"); const CALL_BATCH_SIZE: u64 = 250u64; - const BLS_PK_LEN: usize = 48; let mut keys = vec![]; let mut offset = 0; @@ -301,12 +300,12 @@ async fn fetch_lido_registry_keys( .pubkeys; ensure!( - pubkeys.len() % BLS_PK_LEN == 0, - "unexpected number of keys in batch, expected multiple of {BLS_PK_LEN}, got {}", + pubkeys.len() % BLS_PUBLIC_KEY_BYTES_LEN == 0, + "unexpected number of keys in batch, expected multiple of {BLS_PUBLIC_KEY_BYTES_LEN}, got {}", pubkeys.len() ); - for chunk in pubkeys.chunks(BLS_PK_LEN) { + for chunk in pubkeys.chunks(BLS_PUBLIC_KEY_BYTES_LEN) { keys.push( BlsPublicKey::deserialize(chunk) .map_err(|_| eyre::eyre!("invalid BLS public key"))?, From 6c8c33001c0c0b411b51b9eb836724ff144464ef Mon Sep 17 00:00:00 2001 From: eltitanb Date: Sun, 27 Jul 2025 23:02:37 +0100 Subject: [PATCH 09/12] move bls types in common --- benches/pbs/src/main.rs | 4 ++-- bin/src/lib.rs | 4 ++-- crates/common/src/commit/client.rs | 3 +-- crates/common/src/commit/request.rs | 3 +-- crates/common/src/config/mux.rs | 6 +++--- crates/common/src/config/pbs.rs | 6 +++--- crates/common/src/config/utils.rs | 3 ++- crates/common/src/pbs/error.rs | 2 +- crates/common/src/pbs/relay.rs | 4 ++-- crates/common/src/pbs/types/beacon_block.rs | 2 +- crates/common/src/pbs/types/blinded_block_body.rs | 2 +- crates/common/src/pbs/types/execution_requests.rs | 2 +- crates/common/src/pbs/types/get_header.rs | 2 +- crates/common/src/pbs/types/mod.rs | 4 ---- crates/common/src/signature.rs | 3 +-- crates/common/src/signer/loader.rs | 4 ++-- crates/common/src/signer/schemes/bls.rs | 3 +-- crates/common/src/signer/store.rs | 3 +-- crates/common/src/signer/types.rs | 2 +- crates/common/src/types.rs | 4 ++++ crates/common/src/utils.rs | 2 +- crates/pbs/src/mev_boost/get_header.rs | 10 +++++----- crates/pbs/src/state.rs | 3 ++- crates/signer/src/manager/dirk.rs | 3 +-- crates/signer/src/manager/local.rs | 3 +-- tests/src/mock_relay.rs | 4 ++-- tests/src/mock_validator.rs | 5 ++++- tests/src/utils.rs | 4 ++-- tests/tests/pbs_post_validators.rs | 5 ++++- tests/tests/signer_jwt_auth.rs | 3 +-- 30 files changed, 54 insertions(+), 54 deletions(-) diff --git a/benches/pbs/src/main.rs b/benches/pbs/src/main.rs index 16ee0dd5..7b852a43 100644 --- a/benches/pbs/src/main.rs +++ b/benches/pbs/src/main.rs @@ -3,8 +3,8 @@ use std::time::{Duration, Instant}; use alloy::primitives::B256; use cb_common::{ config::RelayConfig, - pbs::{BlsPublicKey, BlsSecretKey, GetHeaderResponse, RelayClient, RelayEntry}, - types::Chain, + pbs::{GetHeaderResponse, RelayClient, RelayEntry}, + types::{BlsPublicKey, BlsSecretKey, Chain}, utils::TestRandomSeed, }; use cb_tests::mock_relay::{start_mock_relay_service, MockRelayState}; diff --git a/bin/src/lib.rs b/bin/src/lib.rs index 6f44c7f9..e0747d2c 100644 --- a/bin/src/lib.rs +++ b/bin/src/lib.rs @@ -9,9 +9,9 @@ pub mod prelude { load_builder_module_config, load_commit_module_config, load_pbs_config, load_pbs_custom_config, LogsSettings, StartCommitModuleConfig, PBS_MODULE_NAME, }, - pbs::{BlsPublicKey, BlsSignature, BuilderEvent, BuilderEventClient, OnBuilderApiEvent}, + pbs::{BuilderEvent, BuilderEventClient, OnBuilderApiEvent}, signer::EcdsaSignature, - types::Chain, + types::{BlsPublicKey, BlsSignature, Chain}, utils::{initialize_tracing_log, utcnow_ms, utcnow_ns, utcnow_sec, utcnow_us}, }; pub use cb_metrics::provider::MetricsProvider; diff --git a/crates/common/src/commit/client.rs b/crates/common/src/commit/client.rs index d4af8b3d..3fe0ab9c 100644 --- a/crates/common/src/commit/client.rs +++ b/crates/common/src/commit/client.rs @@ -16,9 +16,8 @@ use super::{ }; use crate::{ constants::SIGNER_JWT_EXPIRATION, - pbs::{BlsPublicKey, BlsSignature}, signer::EcdsaSignature, - types::{Jwt, ModuleId}, + types::{BlsPublicKey, BlsSignature, Jwt, ModuleId}, utils::create_jwt, DEFAULT_REQUEST_TIMEOUT, }; diff --git a/crates/common/src/commit/request.rs b/crates/common/src/commit/request.rs index c148dc93..afa01807 100644 --- a/crates/common/src/commit/request.rs +++ b/crates/common/src/commit/request.rs @@ -14,9 +14,8 @@ use tree_hash_derive::TreeHash; use crate::{ constants::COMMIT_BOOST_DOMAIN, - pbs::{BlsPublicKey, BlsSignature}, signature::verify_signed_message, - types::Chain, + types::{BlsPublicKey, BlsSignature, Chain}, }; pub trait ProxyId: Debug + Clone + TreeHash + Display { diff --git a/crates/common/src/config/mux.rs b/crates/common/src/config/mux.rs index fe027a90..996e6803 100644 --- a/crates/common/src/config/mux.rs +++ b/crates/common/src/config/mux.rs @@ -21,8 +21,8 @@ use url::Url; use super::{load_optional_env_var, PbsConfig, RelayConfig, MUX_PATH_ENV}; use crate::{ config::{remove_duplicate_keys, safe_read_http_response}, - pbs::{BlsPublicKey, RelayClient}, - types::Chain, + pbs::RelayClient, + types::{BlsPublicKey, Chain}, }; #[derive(Debug, Deserialize, Serialize)] @@ -460,7 +460,7 @@ mod tests { .pubkeys; let mut vec = vec![]; - for chunk in pubkeys.chunks(48) { + for chunk in pubkeys.chunks(BLS_PUBLIC_KEY_BYTES_LEN) { vec.push( BlsPublicKey::deserialize(chunk) .map_err(|_| eyre::eyre!("invalid BLS public key"))?, diff --git a/crates/common/src/config/pbs.rs b/crates/common/src/config/pbs.rs index 2d1221f2..0415da5b 100644 --- a/crates/common/src/config/pbs.rs +++ b/crates/common/src/config/pbs.rs @@ -25,10 +25,10 @@ use crate::{ SIGNER_URL_ENV, }, pbs::{ - BlsPublicKey, BuilderEventPublisher, DefaultTimeout, RelayClient, RelayEntry, - DEFAULT_PBS_PORT, LATE_IN_SLOT_TIME_MS, REGISTER_VALIDATOR_RETRY_LIMIT, + BuilderEventPublisher, DefaultTimeout, RelayClient, RelayEntry, DEFAULT_PBS_PORT, + LATE_IN_SLOT_TIME_MS, REGISTER_VALIDATOR_RETRY_LIMIT, }, - types::{Chain, Jwt, ModuleId}, + types::{BlsPublicKey, Chain, Jwt, ModuleId}, utils::{ as_eth_str, default_bool, default_host, default_u16, default_u256, default_u32, default_u64, WEI_PER_ETH, diff --git a/crates/common/src/config/utils.rs b/crates/common/src/config/utils.rs index f6e0bc21..906c45e2 100644 --- a/crates/common/src/config/utils.rs +++ b/crates/common/src/config/utils.rs @@ -5,7 +5,8 @@ use serde::de::DeserializeOwned; use super::JWTS_ENV; use crate::{ - config::MUXER_HTTP_MAX_LENGTH, pbs::BlsPublicKey, types::ModuleId, + config::MUXER_HTTP_MAX_LENGTH, + types::{BlsPublicKey, ModuleId}, utils::read_chunked_body_with_max, }; diff --git a/crates/common/src/pbs/error.rs b/crates/common/src/pbs/error.rs index 2ca40e38..dd91ec45 100644 --- a/crates/common/src/pbs/error.rs +++ b/crates/common/src/pbs/error.rs @@ -1,7 +1,7 @@ use alloy::primitives::{B256, U256}; use thiserror::Error; -use crate::{pbs::BlsPublicKey, utils::ResponseReadError}; +use crate::{types::BlsPublicKey, utils::ResponseReadError}; #[derive(Debug, Error)] pub enum PbsError { diff --git a/crates/common/src/pbs/relay.rs b/crates/common/src/pbs/relay.rs index afb715de..789793c7 100644 --- a/crates/common/src/pbs/relay.rs +++ b/crates/common/src/pbs/relay.rs @@ -11,7 +11,7 @@ use super::{ error::PbsError, HEADER_VERSION_KEY, HEADER_VERSION_VALUE, }; -use crate::{config::RelayConfig, pbs::BlsPublicKey, DEFAULT_REQUEST_TIMEOUT}; +use crate::{config::RelayConfig, types::BlsPublicKey, DEFAULT_REQUEST_TIMEOUT}; /// A parsed entry of the relay url in the format: scheme://pubkey@host #[derive(Debug, Clone)] @@ -131,7 +131,7 @@ mod tests { use alloy::{hex, primitives::B256}; use super::{RelayClient, RelayEntry}; - use crate::{config::RelayConfig, pbs::BlsPublicKey}; + use crate::{config::RelayConfig, types::BlsPublicKey}; #[test] fn test_relay_entry() { diff --git a/crates/common/src/pbs/types/beacon_block.rs b/crates/common/src/pbs/types/beacon_block.rs index ad081314..752117fb 100644 --- a/crates/common/src/pbs/types/beacon_block.rs +++ b/crates/common/src/pbs/types/beacon_block.rs @@ -6,7 +6,7 @@ use super::{ blinded_block_body::BlindedBeaconBlockBodyElectra, blobs_bundle::BlobsBundle, execution_payload::ExecutionPayload, spec::ElectraSpec, utils::VersionedResponse, }; -use crate::pbs::BlsSignature; +use crate::types::BlsSignature; #[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] /// Sent to relays in submit_block diff --git a/crates/common/src/pbs/types/blinded_block_body.rs b/crates/common/src/pbs/types/blinded_block_body.rs index b09f3ab0..4acd3dd1 100644 --- a/crates/common/src/pbs/types/blinded_block_body.rs +++ b/crates/common/src/pbs/types/blinded_block_body.rs @@ -7,7 +7,7 @@ use super::{ execution_payload::ExecutionPayloadHeader, execution_requests::ExecutionRequests, kzg::KzgCommitments, spec::EthSpec, utils::*, }; -use crate::pbs::{BlsPublicKey, BlsSignature}; +use crate::types::{BlsPublicKey, BlsSignature}; #[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] #[serde(deny_unknown_fields)] diff --git a/crates/common/src/pbs/types/execution_requests.rs b/crates/common/src/pbs/types/execution_requests.rs index 506c4468..2c48f24a 100644 --- a/crates/common/src/pbs/types/execution_requests.rs +++ b/crates/common/src/pbs/types/execution_requests.rs @@ -5,7 +5,7 @@ use ssz_types::VariableList; use tree_hash_derive::TreeHash; use super::spec::EthSpec; -use crate::pbs::{BlsPublicKey, BlsSignature}; +use crate::types::{BlsPublicKey, BlsSignature}; #[derive(Debug, Default, Clone, Serialize, Deserialize, Encode, Decode, TreeHash)] pub struct ExecutionRequests { diff --git a/crates/common/src/pbs/types/get_header.rs b/crates/common/src/pbs/types/get_header.rs index e8e7fc7d..b66f7061 100644 --- a/crates/common/src/pbs/types/get_header.rs +++ b/crates/common/src/pbs/types/get_header.rs @@ -8,7 +8,7 @@ use super::{ execution_payload::ExecutionPayloadHeader, execution_requests::ExecutionRequests, kzg::KzgCommitments, spec::ElectraSpec, utils::VersionedResponse, }; -use crate::pbs::{BlsPublicKey, BlsSignature}; +use crate::types::{BlsPublicKey, BlsSignature}; #[derive(Debug, Serialize, Deserialize, Clone)] pub struct GetHeaderParams { diff --git a/crates/common/src/pbs/types/mod.rs b/crates/common/src/pbs/types/mod.rs index d96c577f..e22c4a2f 100644 --- a/crates/common/src/pbs/types/mod.rs +++ b/crates/common/src/pbs/types/mod.rs @@ -29,7 +29,3 @@ pub use kzg::{ }; pub use spec::{ElectraSpec, EthSpec}; pub use utils::VersionedResponse; - -pub type BlsPublicKey = lh_types::PublicKey; -pub type BlsSignature = lh_types::Signature; -pub type BlsSecretKey = lh_types::SecretKey; diff --git a/crates/common/src/signature.rs b/crates/common/src/signature.rs index 5fc084aa..9753a9a1 100644 --- a/crates/common/src/signature.rs +++ b/crates/common/src/signature.rs @@ -4,9 +4,8 @@ use tree_hash_derive::TreeHash; use crate::{ constants::{COMMIT_BOOST_DOMAIN, GENESIS_VALIDATORS_ROOT}, - pbs::{BlsPublicKey, BlsSecretKey, BlsSignature}, signer::verify_bls_signature, - types::Chain, + types::{BlsPublicKey, BlsSecretKey, BlsSignature, Chain}, }; pub fn sign_message(secret_key: &BlsSecretKey, msg: B256) -> BlsSignature { diff --git a/crates/common/src/signer/loader.rs b/crates/common/src/signer/loader.rs index a5855f42..f611f359 100644 --- a/crates/common/src/signer/loader.rs +++ b/crates/common/src/signer/loader.rs @@ -19,8 +19,8 @@ use unicode_normalization::UnicodeNormalization; use super::{BlsSigner, EcdsaSigner, PrysmDecryptedKeystore, PrysmKeystore}; use crate::{ config::{load_env_var, SIGNER_DIR_KEYS_ENV, SIGNER_DIR_SECRETS_ENV, SIGNER_KEYS_ENV}, - pbs::BlsPublicKey, signer::ConsensusSigner, + types::BlsPublicKey, }; #[derive(Debug, Serialize, Deserialize, Clone)] @@ -308,11 +308,11 @@ mod tests { use super::{load_from_lighthouse_format, load_from_lodestar_format, FileKey}; use crate::{ - pbs::BlsPublicKey, signer::{ loader::{load_from_prysm_format, load_from_teku_format}, BlsSigner, }, + types::BlsPublicKey, }; #[test] diff --git a/crates/common/src/signer/schemes/bls.rs b/crates/common/src/signer/schemes/bls.rs index 3018bc4a..8525f015 100644 --- a/crates/common/src/signer/schemes/bls.rs +++ b/crates/common/src/signer/schemes/bls.rs @@ -2,9 +2,8 @@ use alloy::primitives::B256; use tree_hash::TreeHash; use crate::{ - pbs::{BlsPublicKey, BlsSecretKey, BlsSignature}, signature::sign_commit_boost_root, - types::Chain, + types::{BlsPublicKey, BlsSecretKey, BlsSignature, Chain}, }; #[derive(Clone)] diff --git a/crates/common/src/signer/store.rs b/crates/common/src/signer/store.rs index b1705597..41720ff3 100644 --- a/crates/common/src/signer/store.rs +++ b/crates/common/src/signer/store.rs @@ -27,9 +27,8 @@ use super::{load_bls_signer, load_ecdsa_signer}; use crate::{ commit::request::{EncryptionScheme, ProxyDelegation, ProxyId, SignedProxyDelegation}, config::{load_env_var, PROXY_DIR_ENV, PROXY_DIR_KEYS_ENV, PROXY_DIR_SECRETS_ENV}, - pbs::{BlsPublicKey, BlsSignature}, signer::{BlsProxySigner, BlsSigner, EcdsaProxySigner, EcdsaSigner, ProxySigners}, - types::ModuleId, + types::{BlsPublicKey, BlsSignature, ModuleId}, }; #[derive(Debug, Serialize, Deserialize)] diff --git a/crates/common/src/signer/types.rs b/crates/common/src/signer/types.rs index 581518c4..60878c84 100644 --- a/crates/common/src/signer/types.rs +++ b/crates/common/src/signer/types.rs @@ -11,8 +11,8 @@ use serde::{ use super::EcdsaSigner; use crate::{ commit::request::{SignedProxyDelegationBls, SignedProxyDelegationEcdsa}, - pbs::BlsPublicKey, signer::BlsSigner, + types::BlsPublicKey, }; // For extra safety and to avoid risking signing malicious messages, use a proxy diff --git a/crates/common/src/types.rs b/crates/common/src/types.rs index b1060a87..508aba96 100644 --- a/crates/common/src/types.rs +++ b/crates/common/src/types.rs @@ -7,6 +7,10 @@ use serde::{Deserialize, Serialize}; use crate::{constants::APPLICATION_BUILDER_DOMAIN, signature::compute_domain}; +pub type BlsPublicKey = lh_types::PublicKey; +pub type BlsSignature = lh_types::Signature; +pub type BlsSecretKey = lh_types::SecretKey; + #[derive(Clone, Debug, Display, PartialEq, Eq, Hash, Deref, From, Into, Serialize, Deserialize)] #[into(owned, ref, ref_mut)] #[serde(transparent)] diff --git a/crates/common/src/utils.rs b/crates/common/src/utils.rs index 6130b1a2..b7666ab9 100644 --- a/crates/common/src/utils.rs +++ b/crates/common/src/utils.rs @@ -434,7 +434,7 @@ pub trait TestRandomSeed: TestRandom { where Self: Sized, { - let mut rng = XorShiftRng::from_seed([42; 16]); + let mut rng = XorShiftRng::from_entropy(); Self::random_for_test(&mut rng) } } diff --git a/crates/pbs/src/mev_boost/get_header.rs b/crates/pbs/src/mev_boost/get_header.rs index f5d109e0..196128f6 100644 --- a/crates/pbs/src/mev_boost/get_header.rs +++ b/crates/pbs/src/mev_boost/get_header.rs @@ -13,11 +13,11 @@ use cb_common::{ constants::APPLICATION_BUILDER_DOMAIN, pbs::{ error::{PbsError, ValidationError}, - BlsPublicKey, BlsSignature, GetHeaderParams, GetHeaderResponse, RelayClient, - VersionedResponse, EMPTY_TX_ROOT_HASH, HEADER_START_TIME_UNIX_MS, + GetHeaderParams, GetHeaderResponse, RelayClient, VersionedResponse, EMPTY_TX_ROOT_HASH, + HEADER_START_TIME_UNIX_MS, }, signature::verify_signed_message, - types::Chain, + types::{BlsPublicKey, BlsSignature, Chain}, utils::{ get_user_agent_with_version, ms_into_slot, read_chunked_body_with_max, timestamp_of_slot_start_sec, utcnow_ms, @@ -506,9 +506,9 @@ fn extra_validation( mod tests { use alloy::primitives::{B256, U256}; use cb_common::{ - pbs::{error::ValidationError, BlsSecretKey, EMPTY_TX_ROOT_HASH}, + pbs::{error::ValidationError, EMPTY_TX_ROOT_HASH}, signature::sign_builder_message, - types::Chain, + types::{BlsSecretKey, Chain}, utils::{timestamp_of_slot_start_sec, TestRandomSeed}, }; diff --git a/crates/pbs/src/state.rs b/crates/pbs/src/state.rs index 3381af9d..4fc18e15 100644 --- a/crates/pbs/src/state.rs +++ b/crates/pbs/src/state.rs @@ -2,7 +2,8 @@ use std::sync::Arc; use cb_common::{ config::{PbsConfig, PbsModuleConfig}, - pbs::{BlsPublicKey, BuilderEvent, RelayClient}, + pbs::{BuilderEvent, RelayClient}, + types::BlsPublicKey, }; use parking_lot::RwLock; diff --git a/crates/signer/src/manager/dirk.rs b/crates/signer/src/manager/dirk.rs index c3d2d717..7e98324f 100644 --- a/crates/signer/src/manager/dirk.rs +++ b/crates/signer/src/manager/dirk.rs @@ -6,10 +6,9 @@ use cb_common::{ commit::request::{ConsensusProxyMap, ProxyDelegation, SignedProxyDelegation}, config::{DirkConfig, DirkHostConfig}, constants::COMMIT_BOOST_DOMAIN, - pbs::{BlsPublicKey, BlsSignature}, signature::compute_domain, signer::ProxyStore, - types::{Chain, ModuleId}, + types::{BlsPublicKey, BlsSignature, Chain, ModuleId}, }; use eyre::{bail, OptionExt}; use futures::{future::join_all, stream::FuturesUnordered, FutureExt, StreamExt}; diff --git a/crates/signer/src/manager/local.rs b/crates/signer/src/manager/local.rs index f2b6cb9f..d21a2967 100644 --- a/crates/signer/src/manager/local.rs +++ b/crates/signer/src/manager/local.rs @@ -6,12 +6,11 @@ use cb_common::{ ConsensusProxyMap, ProxyDelegationBls, ProxyDelegationEcdsa, ProxyId, SignedProxyDelegationBls, SignedProxyDelegationEcdsa, }, - pbs::{BlsPublicKey, BlsSignature}, signer::{ BlsProxySigner, BlsSigner, ConsensusSigner, EcdsaProxySigner, EcdsaSignature, EcdsaSigner, ProxySigners, ProxyStore, }, - types::{Chain, ModuleId}, + types::{BlsPublicKey, BlsSignature, Chain, ModuleId}, }; use tree_hash::TreeHash; diff --git a/tests/src/mock_relay.rs b/tests/src/mock_relay.rs index b058327d..147738b7 100644 --- a/tests/src/mock_relay.rs +++ b/tests/src/mock_relay.rs @@ -16,14 +16,14 @@ use axum::{ }; use cb_common::{ pbs::{ - BlindedBeaconBlock, BlsSecretKey, ExecutionPayloadHeaderMessageElectra, ExecutionRequests, + BlindedBeaconBlock, ExecutionPayloadHeaderMessageElectra, ExecutionRequests, GetHeaderParams, GetHeaderResponse, KzgProof, SignedBlindedBeaconBlock, SignedExecutionPayloadHeader, SubmitBlindedBlockResponse, VersionedResponse, BUILDER_API_PATH, GET_HEADER_PATH, GET_STATUS_PATH, REGISTER_VALIDATOR_PATH, SUBMIT_BLOCK_PATH, }, signature::sign_builder_root, - types::Chain, + types::{BlsSecretKey, Chain}, utils::timestamp_of_slot_start_sec, }; use cb_pbs::MAX_SIZE_SUBMIT_BLOCK_RESPONSE; diff --git a/tests/src/mock_validator.rs b/tests/src/mock_validator.rs index a70ff84d..dee63231 100644 --- a/tests/src/mock_validator.rs +++ b/tests/src/mock_validator.rs @@ -1,5 +1,8 @@ use alloy::{hex, primitives::B256, rpc::types::beacon::relay::ValidatorRegistration}; -use cb_common::pbs::{BlsPublicKey, RelayClient, SignedBlindedBeaconBlock}; +use cb_common::{ + pbs::{RelayClient, SignedBlindedBeaconBlock}, + types::BlsPublicKey, +}; use reqwest::Response; use crate::utils::generate_mock_relay; diff --git a/tests/src/utils.rs b/tests/src/utils.rs index 28d1a82b..e44144a8 100644 --- a/tests/src/utils.rs +++ b/tests/src/utils.rs @@ -10,12 +10,12 @@ use cb_common::{ PbsConfig, PbsModuleConfig, RelayConfig, SignerConfig, SignerType, StartSignerConfig, SIGNER_IMAGE_DEFAULT, }, - pbs::{BlsPublicKey, RelayClient, RelayEntry}, + pbs::{RelayClient, RelayEntry}, signer::{ SignerLoader, DEFAULT_JWT_AUTH_FAIL_LIMIT, DEFAULT_JWT_AUTH_FAIL_TIMEOUT_SECONDS, DEFAULT_SIGNER_PORT, }, - types::{Chain, ModuleId}, + types::{BlsPublicKey, Chain, ModuleId}, utils::default_host, }; use eyre::Result; diff --git a/tests/tests/pbs_post_validators.rs b/tests/tests/pbs_post_validators.rs index 8411941c..09a471a7 100644 --- a/tests/tests/pbs_post_validators.rs +++ b/tests/tests/pbs_post_validators.rs @@ -1,7 +1,10 @@ use std::{sync::Arc, time::Duration}; use alloy::rpc::types::beacon::relay::ValidatorRegistration; -use cb_common::{pbs::BlsPublicKey, signer::random_secret, types::Chain}; +use cb_common::{ + signer::random_secret, + types::{BlsPublicKey, Chain}, +}; use cb_pbs::{DefaultBuilderApi, PbsService, PbsState}; use cb_tests::{ mock_relay::{start_mock_relay_service, MockRelayState}, diff --git a/tests/tests/signer_jwt_auth.rs b/tests/tests/signer_jwt_auth.rs index 090517bf..054aa781 100644 --- a/tests/tests/signer_jwt_auth.rs +++ b/tests/tests/signer_jwt_auth.rs @@ -4,9 +4,8 @@ use alloy::hex; use cb_common::{ commit::{constants::GET_PUBKEYS_PATH, request::GetPubkeysResponse}, config::StartSignerConfig, - pbs::BlsPublicKey, signer::{SignerLoader, ValidatorKeysFormat}, - types::{Chain, ModuleId}, + types::{BlsPublicKey, Chain, ModuleId}, utils::create_jwt, }; use cb_signer::service::SigningService; From a9000e9b0c5117950132a0334ca5b6266171a387 Mon Sep 17 00:00:00 2001 From: eltitanb Date: Sun, 27 Jul 2025 23:10:05 +0100 Subject: [PATCH 10/12] replace builder domain with b256 --- crates/common/src/types.rs | 49 +++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/crates/common/src/types.rs b/crates/common/src/types.rs index 508aba96..40c3a990 100644 --- a/crates/common/src/types.rs +++ b/crates/common/src/types.rs @@ -1,6 +1,6 @@ use std::path::PathBuf; -use alloy::primitives::{hex, Bytes, B256}; +use alloy::primitives::{b256, hex, Bytes, B256}; use derive_more::{Deref, Display, From, Into}; use eyre::{bail, Context}; use serde::{Deserialize, Serialize}; @@ -84,11 +84,11 @@ impl Chain { pub fn builder_domain(&self) -> B256 { match self { - Chain::Mainnet => KnownChain::Mainnet.builder_domain().into(), - Chain::Holesky => KnownChain::Holesky.builder_domain().into(), - Chain::Sepolia => KnownChain::Sepolia.builder_domain().into(), - Chain::Helder => KnownChain::Helder.builder_domain().into(), - Chain::Hoodi => KnownChain::Hoodi.builder_domain().into(), + Chain::Mainnet => KnownChain::Mainnet.builder_domain(), + Chain::Holesky => KnownChain::Holesky.builder_domain(), + Chain::Sepolia => KnownChain::Sepolia.builder_domain(), + Chain::Helder => KnownChain::Helder.builder_domain(), + Chain::Hoodi => KnownChain::Hoodi.builder_domain(), Chain::Custom { .. } => compute_domain(*self, APPLICATION_BUILDER_DOMAIN), } } @@ -153,28 +153,23 @@ impl KnownChain { } } - pub fn builder_domain(&self) -> [u8; 32] { + pub fn builder_domain(&self) -> B256 { match self { - KnownChain::Mainnet => [ - 0, 0, 0, 1, 245, 165, 253, 66, 209, 106, 32, 48, 39, 152, 239, 110, 211, 9, 151, - 155, 67, 0, 61, 35, 32, 217, 240, 232, 234, 152, 49, 169, - ], - KnownChain::Holesky => [ - 0, 0, 0, 1, 91, 131, 162, 55, 89, 197, 96, 178, 208, 198, 69, 118, 225, 220, 252, - 52, 234, 148, 196, 152, 143, 62, 13, 159, 119, 240, 83, 135, - ], - KnownChain::Sepolia => [ - 0, 0, 0, 1, 211, 1, 7, 120, 205, 8, 238, 81, 75, 8, 254, 103, 182, 197, 3, 181, 16, - 152, 122, 76, 228, 63, 66, 48, 109, 151, 198, 124, - ], - KnownChain::Helder => [ - 0, 0, 0, 1, 148, 196, 26, 244, 132, 255, 247, 150, 73, 105, 224, 189, 217, 34, 248, - 45, 255, 15, 75, 232, 122, 96, 208, 102, 76, 201, 209, 255, - ], - KnownChain::Hoodi => [ - 0, 0, 0, 1, 113, 145, 3, 81, 30, 250, 79, 19, 98, 255, 42, 80, 153, 108, 204, 243, - 41, 204, 132, 203, 65, 12, 94, 92, 125, 53, 29, 3, - ], + KnownChain::Mainnet => { + b256!("0x00000001f5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a9") + } + KnownChain::Holesky => { + b256!("0x000000015b83a23759c560b2d0c64576e1dcfc34ea94c4988f3e0d9f77f05387") + } + KnownChain::Sepolia => { + b256!("0x00000001d3010778cd08ee514b08fe67b6c503b510987a4ce43f42306d97c67c") + } + KnownChain::Helder => { + b256!("0x0000000194c41af484fff7964969e0bdd922f82dff0f4be87a60d0664cc9d1ff") + } + KnownChain::Hoodi => { + b256!("0x00000001719103511efa4f1362ff2a50996cccf329cc84cb410c5e5c7d351d03") + } } } From 19329d6172e6e5d4a3313e88044f51227e4bfe12 Mon Sep 17 00:00:00 2001 From: eltitanb Date: Sun, 27 Jul 2025 23:24:39 +0100 Subject: [PATCH 11/12] test util --- crates/common/src/config/mux.rs | 14 +++------- crates/common/src/pbs/relay.rs | 10 +++---- crates/common/src/signer/loader.rs | 42 +++++++++++++----------------- crates/common/src/signer/store.rs | 14 +++------- crates/common/src/utils.rs | 20 ++++++++++++-- tests/src/mock_validator.rs | 7 ++--- tests/tests/signer_jwt_auth.rs | 9 +++---- 7 files changed, 56 insertions(+), 60 deletions(-) diff --git a/crates/common/src/config/mux.rs b/crates/common/src/config/mux.rs index 996e6803..21c64b6f 100644 --- a/crates/common/src/config/mux.rs +++ b/crates/common/src/config/mux.rs @@ -432,7 +432,7 @@ mod tests { use super::*; use crate::{ config::{HTTP_TIMEOUT_SECONDS_DEFAULT, MUXER_HTTP_MAX_LENGTH}, - utils::{set_ignore_content_length, ResponseReadError}, + utils::{bls_pubkey_from_hex_unchecked, set_ignore_content_length, ResponseReadError}, }; const TEST_HTTP_TIMEOUT: u64 = 2; @@ -487,15 +487,9 @@ mod tests { // NOTE: requires that ssv_data.json dpesn't change assert_eq!(response.validators.len(), 3); let expected_pubkeys = [ - BlsPublicKey::deserialize( - &alloy::hex!("967ba17a3e7f82a25aa5350ec34d6923e28ad8237b5a41efe2c5e325240d74d87a015bf04634f21900963539c8229b2a") - ).unwrap(), - BlsPublicKey::deserialize( - &alloy::hex!("ac769e8cec802e8ffee34de3253be8f438a0c17ee84bdff0b6730280d24b5ecb77ebc9c985281b41ee3bda8663b6658c"), - ).unwrap(), - BlsPublicKey::deserialize( - &alloy::hex!("8c866a5a05f3d45c49b457e29365259021a509c5daa82e124f9701a960ee87b8902e87175315ab638a3d8b1115b23639"), - ).unwrap(), + bls_pubkey_from_hex_unchecked("967ba17a3e7f82a25aa5350ec34d6923e28ad8237b5a41efe2c5e325240d74d87a015bf04634f21900963539c8229b2a"), + bls_pubkey_from_hex_unchecked("ac769e8cec802e8ffee34de3253be8f438a0c17ee84bdff0b6730280d24b5ecb77ebc9c985281b41ee3bda8663b6658c"), + bls_pubkey_from_hex_unchecked("8c866a5a05f3d45c49b457e29365259021a509c5daa82e124f9701a960ee87b8902e87175315ab638a3d8b1115b23639"), ]; for (i, validator) in response.validators.iter().enumerate() { assert_eq!(validator.pubkey, expected_pubkeys[i]); diff --git a/crates/common/src/pbs/relay.rs b/crates/common/src/pbs/relay.rs index 789793c7..3ad04999 100644 --- a/crates/common/src/pbs/relay.rs +++ b/crates/common/src/pbs/relay.rs @@ -128,14 +128,14 @@ impl RelayClient { mod tests { use std::collections::HashMap; - use alloy::{hex, primitives::B256}; + use alloy::primitives::B256; use super::{RelayClient, RelayEntry}; - use crate::{config::RelayConfig, types::BlsPublicKey}; + use crate::{config::RelayConfig, utils::bls_pubkey_from_hex_unchecked}; #[test] fn test_relay_entry() { - let pubkey = BlsPublicKey::deserialize(&hex!("0xac6e77dfe25ecd6110b8e780608cce0dab71fdd5ebea22a16c0205200f2f8e2e3ad3b71d3499c54ad14d6c21b41a37ae")).unwrap(); + let pubkey = bls_pubkey_from_hex_unchecked("0xac6e77dfe25ecd6110b8e780608cce0dab71fdd5ebea22a16c0205200f2f8e2e3ad3b71d3499c54ad14d6c21b41a37ae"); let s = format!("http://{pubkey}@abc.xyz/"); let parsed = serde_json::from_str::(&format!("\"{s}\"")).unwrap(); @@ -149,7 +149,7 @@ mod tests { fn test_relay_url() { let slot = 0; let parent_hash = B256::ZERO; - let validator_pubkey = BlsPublicKey::deserialize(&hex!("0xac6e77dfe25ecd6110b8e780608cce0dab71fdd5ebea22a16c0205200f2f8e2e3ad3b71d3499c54ad14d6c21b41a37ae")).unwrap(); + let validator_pubkey = bls_pubkey_from_hex_unchecked("0xac6e77dfe25ecd6110b8e780608cce0dab71fdd5ebea22a16c0205200f2f8e2e3ad3b71d3499c54ad14d6c21b41a37ae"); let expected = format!("http://0xa1cec75a3f0661e99299274182938151e8433c61a19222347ea1313d839229cb4ce4e3e5aa2bdeb71c8fcf1b084963c2@abc.xyz/eth/v1/builder/header/{slot}/{parent_hash}/{validator_pubkey}"); let relay_config = r#" @@ -183,7 +183,7 @@ mod tests { fn test_relay_url_with_get_params() { let slot = 0; let parent_hash = B256::ZERO; - let validator_pubkey = BlsPublicKey::deserialize(&hex!("0xac6e77dfe25ecd6110b8e780608cce0dab71fdd5ebea22a16c0205200f2f8e2e3ad3b71d3499c54ad14d6c21b41a37ae")).unwrap(); + let validator_pubkey = bls_pubkey_from_hex_unchecked("0xac6e77dfe25ecd6110b8e780608cce0dab71fdd5ebea22a16c0205200f2f8e2e3ad3b71d3499c54ad14d6c21b41a37ae"); // Note: HashMap iteration order is not guaranteed, so we can't predict the // exact order of parameters Instead of hard-coding the order, we'll // check that both parameters are present in the URL diff --git a/crates/common/src/signer/loader.rs b/crates/common/src/signer/loader.rs index f611f359..c45c31d9 100644 --- a/crates/common/src/signer/loader.rs +++ b/crates/common/src/signer/loader.rs @@ -20,7 +20,7 @@ use super::{BlsSigner, EcdsaSigner, PrysmDecryptedKeystore, PrysmKeystore}; use crate::{ config::{load_env_var, SIGNER_DIR_KEYS_ENV, SIGNER_DIR_SECRETS_ENV, SIGNER_KEYS_ENV}, signer::ConsensusSigner, - types::BlsPublicKey, + utils::bls_pubkey_from_hex, }; #[derive(Debug, Serialize, Deserialize, Clone)] @@ -124,14 +124,12 @@ fn load_from_lighthouse_format( } let maybe_pubkey = path.file_name().and_then(|d| d.to_str())?; - let Ok(decoded) = alloy::primitives::hex::decode(maybe_pubkey) else { - warn!("Invalid pubkey: {}", maybe_pubkey); - return None - }; - - let Ok(pubkey) = BlsPublicKey::deserialize(&decoded) else { - warn!("Invalid pubkey: {}", maybe_pubkey); - return None + let pubkey = match bls_pubkey_from_hex(maybe_pubkey) { + Ok(pubkey) => pubkey, + Err(e) => { + warn!("Invalid pubkey: {}: {}", maybe_pubkey, e); + return None + } }; let ks_path = keys_path.join(maybe_pubkey).join("voting-keystore.json"); @@ -304,15 +302,13 @@ pub fn load_ecdsa_signer(keys_path: PathBuf, secrets_path: PathBuf) -> eyre::Res #[cfg(test)] mod tests { - use alloy::hex; - use super::{load_from_lighthouse_format, load_from_lodestar_format, FileKey}; use crate::{ signer::{ loader::{load_from_prysm_format, load_from_teku_format}, BlsSigner, }, - types::BlsPublicKey, + utils::bls_pubkey_from_hex_unchecked, }; #[test] @@ -333,12 +329,10 @@ mod tests { fn test_correct_load(signers: Vec) { assert_eq!(signers.len(), 2); - assert!(signers.iter().any(|s| s.pubkey() == BlsPublicKey::deserialize(& - hex!("883827193f7627cd04e621e1e8d56498362a52b2a30c9a1c72036eb935c4278dee23d38a24d2f7dda62689886f0c39f4") - ).unwrap())); - assert!(signers.iter().any(|s| s.pubkey() == BlsPublicKey::deserialize(& - hex!("b3a22e4a673ac7a153ab5b3c17a4dbef55f7e47210b20c0cbb0e66df5b36bb49ef808577610b034172e955d2312a61b9") - ).unwrap())); + assert!(signers.iter().any(|s| s.pubkey() == bls_pubkey_from_hex_unchecked("883827193f7627cd04e621e1e8d56498362a52b2a30c9a1c72036eb935c4278dee23d38a24d2f7dda62689886f0c39f4") + )); + assert!(signers.iter().any(|s| s.pubkey() == bls_pubkey_from_hex_unchecked("b3a22e4a673ac7a153ab5b3c17a4dbef55f7e47210b20c0cbb0e66df5b36bb49ef808577610b034172e955d2312a61b9") + )); } #[test] @@ -389,9 +383,9 @@ mod tests { let signers = result.unwrap(); assert_eq!(signers.len(), 1); - assert!(signers[0].pubkey() == BlsPublicKey::deserialize(& - hex!("883827193f7627cd04e621e1e8d56498362a52b2a30c9a1c72036eb935c4278dee23d38a24d2f7dda62689886f0c39f4") - ).unwrap()); + assert!(signers[0].pubkey() == bls_pubkey_from_hex_unchecked( + "883827193f7627cd04e621e1e8d56498362a52b2a30c9a1c72036eb935c4278dee23d38a24d2f7dda62689886f0c39f4" + )); let result = load_from_lodestar_format( "../../tests/data/keystores/teku-keys/".into(), @@ -403,8 +397,8 @@ mod tests { let signers = result.unwrap(); assert_eq!(signers.len(), 1); - assert!(signers[0].pubkey() == BlsPublicKey::deserialize(& - hex!("b3a22e4a673ac7a153ab5b3c17a4dbef55f7e47210b20c0cbb0e66df5b36bb49ef808577610b034172e955d2312a61b9") - ).unwrap()); + assert!(signers[0].pubkey() == bls_pubkey_from_hex_unchecked( + "b3a22e4a673ac7a153ab5b3c17a4dbef55f7e47210b20c0cbb0e66df5b36bb49ef808577610b034172e955d2312a61b9" + )); } } diff --git a/crates/common/src/signer/store.rs b/crates/common/src/signer/store.rs index 41720ff3..cc8cf515 100644 --- a/crates/common/src/signer/store.rs +++ b/crates/common/src/signer/store.rs @@ -533,6 +533,7 @@ mod test { commit::request::{ProxyDelegationBls, SignedProxyDelegationBls}, signer::ConsensusSigner, types::Chain, + utils::bls_pubkey_from_hex_unchecked, }; #[tokio::test] @@ -611,17 +612,8 @@ mod test { assert_eq!(proxy_signers.bls_signers.len(), 1); assert_eq!(proxy_signers.ecdsa_signers.len(), 0); - let proxy_key = BlsPublicKey::deserialize( - &hex::decode( - "a77084280678d9f1efe4ef47a3d62af27872ce82db19a35ee012c4fd5478e6b1123b8869032ba18b2383e8873294f0ba" - ).unwrap() - ).unwrap(); - - let consensus_key = BlsPublicKey::deserialize( - &hex::decode( - "ac5e059177afc33263e95d0be0690138b9a1d79a6e19018086a0362e0c30a50bf9e05a08cb44785724d0b2718c5c7118" - ).unwrap() - ).unwrap(); + let proxy_key = bls_pubkey_from_hex_unchecked("a77084280678d9f1efe4ef47a3d62af27872ce82db19a35ee012c4fd5478e6b1123b8869032ba18b2383e8873294f0ba"); + let consensus_key = bls_pubkey_from_hex_unchecked("ac5e059177afc33263e95d0be0690138b9a1d79a6e19018086a0362e0c30a50bf9e05a08cb44785724d0b2718c5c7118"); let proxy_signer = proxy_signers.bls_signers.get(&proxy_key); diff --git a/crates/common/src/utils.rs b/crates/common/src/utils.rs index b7666ab9..7a475cbf 100644 --- a/crates/common/src/utils.rs +++ b/crates/common/src/utils.rs @@ -5,7 +5,7 @@ use std::{ time::{SystemTime, UNIX_EPOCH}, }; -use alloy::primitives::U256; +use alloy::{hex, primitives::U256}; use axum::http::HeaderValue; use futures::StreamExt; use lh_types::test_utils::{SeedableRng, TestRandom, XorShiftRng}; @@ -27,7 +27,7 @@ use crate::{ config::LogsSettings, constants::SIGNER_JWT_EXPIRATION, pbs::HEADER_VERSION_VALUE, - types::{Chain, Jwt, JwtClaims, ModuleId}, + types::{BlsPublicKey, Chain, Jwt, JwtClaims, ModuleId}, }; const MILLIS_PER_SECOND: u64 = 1_000; @@ -441,6 +441,22 @@ pub trait TestRandomSeed: TestRandom { impl TestRandomSeed for T {} +pub fn bls_pubkey_from_hex(hex: &str) -> eyre::Result { + let Ok(bytes) = hex::decode(hex) else { + eyre::bail!("invalid hex pubkey: {hex}"); + }; + + let pubkey = BlsPublicKey::deserialize(&bytes) + .map_err(|e| eyre::eyre!("invalid hex pubkey: {hex}: {e:?}"))?; + + Ok(pubkey) +} + +#[cfg(test)] +pub fn bls_pubkey_from_hex_unchecked(hex: &str) -> BlsPublicKey { + bls_pubkey_from_hex(hex).unwrap() +} + #[cfg(test)] mod test { use super::{create_jwt, decode_jwt, validate_jwt}; diff --git a/tests/src/mock_validator.rs b/tests/src/mock_validator.rs index dee63231..853503d7 100644 --- a/tests/src/mock_validator.rs +++ b/tests/src/mock_validator.rs @@ -1,7 +1,8 @@ -use alloy::{hex, primitives::B256, rpc::types::beacon::relay::ValidatorRegistration}; +use alloy::{primitives::B256, rpc::types::beacon::relay::ValidatorRegistration}; use cb_common::{ pbs::{RelayClient, SignedBlindedBeaconBlock}, types::BlsPublicKey, + utils::bls_pubkey_from_hex, }; use reqwest::Response; @@ -13,12 +14,12 @@ pub struct MockValidator { impl MockValidator { pub fn new(port: u16) -> eyre::Result { - let pubkey = BlsPublicKey::deserialize(&hex!("0xac6e77dfe25ecd6110b8e780608cce0dab71fdd5ebea22a16c0205200f2f8e2e3ad3b71d3499c54ad14d6c21b41a37ae")).unwrap(); + let pubkey = bls_pubkey_from_hex("0xac6e77dfe25ecd6110b8e780608cce0dab71fdd5ebea22a16c0205200f2f8e2e3ad3b71d3499c54ad14d6c21b41a37ae")?; Ok(Self { comm_boost: generate_mock_relay(port, pubkey)? }) } pub async fn do_get_header(&self, pubkey: Option) -> eyre::Result { - let default_pubkey = BlsPublicKey::deserialize(&hex!("0xac6e77dfe25ecd6110b8e780608cce0dab71fdd5ebea22a16c0205200f2f8e2e3ad3b71d3499c54ad14d6c21b41a37ae")).unwrap(); + let default_pubkey = bls_pubkey_from_hex("0xac6e77dfe25ecd6110b8e780608cce0dab71fdd5ebea22a16c0205200f2f8e2e3ad3b71d3499c54ad14d6c21b41a37ae")?; let url = self.comm_boost.get_header_url(0, &B256::ZERO, &pubkey.unwrap_or(default_pubkey))?; Ok(self.comm_boost.client.get(url).send().await?) diff --git a/tests/tests/signer_jwt_auth.rs b/tests/tests/signer_jwt_auth.rs index 054aa781..5f8a7274 100644 --- a/tests/tests/signer_jwt_auth.rs +++ b/tests/tests/signer_jwt_auth.rs @@ -1,12 +1,11 @@ use std::{collections::HashMap, time::Duration}; -use alloy::hex; use cb_common::{ commit::{constants::GET_PUBKEYS_PATH, request::GetPubkeysResponse}, config::StartSignerConfig, signer::{SignerLoader, ValidatorKeysFormat}, - types::{BlsPublicKey, Chain, ModuleId}, - utils::create_jwt, + types::{Chain, ModuleId}, + utils::{bls_pubkey_from_hex, create_jwt}, }; use cb_signer::service::SigningService; use cb_tests::utils::{get_signer_config, get_start_signer_config, setup_test_env}; @@ -131,8 +130,8 @@ async fn verify_pubkeys(response: Response) -> Result<()> { let pubkey_json = response.json::().await?; assert_eq!(pubkey_json.keys.len(), 2); let expected_pubkeys = vec![ - BlsPublicKey::deserialize(&hex!("883827193f7627cd04e621e1e8d56498362a52b2a30c9a1c72036eb935c4278dee23d38a24d2f7dda62689886f0c39f4")).unwrap(), - BlsPublicKey::deserialize(&hex!("b3a22e4a673ac7a153ab5b3c17a4dbef55f7e47210b20c0cbb0e66df5b36bb49ef808577610b034172e955d2312a61b9")).unwrap(), + bls_pubkey_from_hex("883827193f7627cd04e621e1e8d56498362a52b2a30c9a1c72036eb935c4278dee23d38a24d2f7dda62689886f0c39f4")?, + bls_pubkey_from_hex("b3a22e4a673ac7a153ab5b3c17a4dbef55f7e47210b20c0cbb0e66df5b36bb49ef808577610b034172e955d2312a61b9")?, ]; for expected in expected_pubkeys { assert!( From 97c67224e1dff9b4b5fb3e6ef35cdfe3b10b9656 Mon Sep 17 00:00:00 2001 From: ltitanb Date: Thu, 14 Aug 2025 23:51:22 +0100 Subject: [PATCH 12/12] fix --- tests/tests/pbs_get_status.rs | 4 ++-- tests/tests/pbs_mux.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/tests/pbs_get_status.rs b/tests/tests/pbs_get_status.rs index 96fecdb9..73a81e51 100644 --- a/tests/tests/pbs_get_status.rs +++ b/tests/tests/pbs_get_status.rs @@ -42,8 +42,8 @@ async fn test_get_status() -> Result<()> { let res = mock_validator.do_get_status().await.expect("failed to get status"); assert_eq!(res.status(), StatusCode::OK); - // Expect two statuses since two relays in config + 2 on startup of the service - assert_eq!(mock_state.received_get_status(), 4); + // Expect two statuses since two relays in config + assert_eq!(mock_state.received_get_status(), 2); Ok(()) } diff --git a/tests/tests/pbs_mux.rs b/tests/tests/pbs_mux.rs index a57449ba..3c4f7a13 100644 --- a/tests/tests/pbs_mux.rs +++ b/tests/tests/pbs_mux.rs @@ -70,7 +70,7 @@ async fn test_mux() -> Result<()> { // Status requests should go to all relays info!("Sending get status"); assert_eq!(mock_validator.do_get_status().await?.status(), StatusCode::OK); - assert_eq!(mock_state.received_get_status(), 6); // default + 2 mux relays were used + 3 on startup of the service + assert_eq!(mock_state.received_get_status(), 3); // default + 2 mux relays were used // Register requests should go to all relays info!("Sending register validator");