diff --git a/bolt-sidecar/src/chain_io/manager.rs b/bolt-sidecar/src/chain_io/manager.rs index 7c25f9427..8479e7bdb 100644 --- a/bolt-sidecar/src/chain_io/manager.rs +++ b/bolt-sidecar/src/chain_io/manager.rs @@ -13,7 +13,9 @@ use eyre::bail; use reqwest::{Client, Url}; use serde::Serialize; -use BoltManagerContract::{BoltManagerContractErrors, BoltManagerContractInstance, ProposerStatus}; +use BoltManagerContract::{ + BoltManagerContractErrors, BoltManagerContractInstance, ProposerStatus, ValidatorDoesNotExist, +}; use crate::config::chain::Chain; @@ -47,10 +49,11 @@ impl BoltManager { /// NOTE: it also checks the operator associated to the `commitment_signer_pubkey` exists. pub async fn verify_validator_pubkeys( &self, - keys: &[BlsPublicKey], + keys: Vec, commitment_signer_pubkey: Address, ) -> eyre::Result> { - let hashes = utils::pubkey_hashes(keys); + let hashes_with_preimages = utils::pubkey_hashes(keys); + let hashes = hashes_with_preimages.keys().cloned().collect::>(); let returndata = self.0.getProposerStatuses(hashes).call().await; @@ -60,7 +63,8 @@ impl BoltManager { for status in &statuses { if !status.active { bail!( - "validator with public key hash {:?} is not active in Bolt", + "validator with public key {:?} and public key hash {:?} is not active in Bolt", + hashes_with_preimages.get(&status.pubkeyHash), status.pubkeyHash ); } else if status.operator != commitment_signer_pubkey { @@ -87,14 +91,16 @@ impl BoltManager { }; match error { - BoltManagerContractErrors::ValidatorDoesNotExist(pubkey_hash) => { - bail!("validator with public key hash {:?} is not registered in Bolt", pubkey_hash); + BoltManagerContractErrors::ValidatorDoesNotExist(ValidatorDoesNotExist { + pubkeyHash: pubkey_hash, + }) => { + bail!("ValidatorDoesNotExist -- validator with public key {:?} and public key hash {:?} is not registered in Bolt", hashes_with_preimages.get(&pubkey_hash), pubkey_hash); } BoltManagerContractErrors::InvalidQuery(_) => { - bail!("invalid zero public key hash"); + bail!("InvalidQuery -- invalid zero public key hash"); } BoltManagerContractErrors::KeyNotFound(_) => { - bail!("operator associated with commitment signer public key {:?} is not registered in Bolt", commitment_signer_pubkey); + bail!("KeyNotFound -- operator associated with commitment signer public key {:?} is not registered in Bolt", commitment_signer_pubkey); } } } @@ -153,7 +159,6 @@ mod tests { use super::BoltManager; #[tokio::test] - #[ignore = "requires Chainbound tailnet"] async fn test_verify_validator_pubkeys() { let url = Url::parse("http://remotebeast:48545").expect("valid url"); let manager = @@ -165,14 +170,14 @@ mod tests { let keys = vec![BlsPublicKey::try_from([0; 48].as_ref()).expect("valid bls public key")]; let commitment_signer_pubkey = Address::ZERO; - let res = manager.verify_validator_pubkeys(&keys, commitment_signer_pubkey).await; + let res = manager.verify_validator_pubkeys(keys, commitment_signer_pubkey).await; assert!(res.unwrap_err().to_string().contains("ValidatorDoesNotExist")); let keys = vec![ BlsPublicKey::try_from( hex!("87cbbfe6f08a0fd424507726cfcf5b9df2b2fd6b78a65a3d7bb6db946dca3102eb8abae32847d5a9a27e414888414c26") .as_ref()).expect("valid bls public key")]; - let res = manager.verify_validator_pubkeys(&keys, commitment_signer_pubkey).await; + let res = manager.verify_validator_pubkeys(keys.clone(), commitment_signer_pubkey).await; assert!( res.unwrap_err().to_string() == generate_operator_keys_mismatch_error( @@ -184,7 +189,7 @@ mod tests { let commitment_signer_pubkey = operator; let res = manager - .verify_validator_pubkeys(&keys, commitment_signer_pubkey) + .verify_validator_pubkeys(keys, commitment_signer_pubkey) .await .expect("active validator and correct operator"); assert!(res[0].active); diff --git a/bolt-sidecar/src/chain_io/utils.rs b/bolt-sidecar/src/chain_io/utils.rs index 92169e4b5..c98a16b12 100644 --- a/bolt-sidecar/src/chain_io/utils.rs +++ b/bolt-sidecar/src/chain_io/utils.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; + use alloy::primitives::{FixedBytes, B512}; use ethereum_consensus::primitives::BlsPublicKey; use reth_primitives::keccak256; @@ -7,10 +9,12 @@ use reth_primitives::keccak256; /// Reference: https://github.com/chainbound/bolt/blob/bec46baae6d7c16dddd81e5e72710ca8e3064f82/bolt-contracts/script/holesky/validators/RegisterValidators.s.sol#L65-L69 pub(crate) type CompressedHash = FixedBytes<20>; -/// Hash the public keys of the proposers. This follows the same -/// implementation done on-chain in the BoltValidators contract. -pub fn pubkey_hashes(keys: &[BlsPublicKey]) -> Vec { - keys.iter().map(pubkey_hash).collect() +/// Hash the public keys of the proposers and return a mapping with the results and their +/// pre-images. +/// +/// This follows the same implementation done on-chain in the BoltValidators contract. +pub fn pubkey_hashes(keys: Vec) -> HashMap { + HashMap::from_iter(keys.into_iter().map(|key| (pubkey_hash(&key), key))) } /// Hash the public key of the proposer. This follows the same diff --git a/bolt-sidecar/src/driver.rs b/bolt-sidecar/src/driver.rs index 7ac118768..59962180e 100644 --- a/bolt-sidecar/src/driver.rs +++ b/bolt-sidecar/src/driver.rs @@ -168,11 +168,12 @@ impl SidecarDriver { { let commitment_signer_pubkey = commitment_signer.public_key(); let available_pubkeys = Vec::from_iter(constraint_signer.available_pubkeys()); + let available_pubkeys_len = available_pubkeys.len(); bolt_manager - .verify_validator_pubkeys(&available_pubkeys, commitment_signer_pubkey) + .verify_validator_pubkeys(available_pubkeys, commitment_signer_pubkey) .await?; info!( - pubkeys_len = available_pubkeys.len(), + available_pubkeys_len, commitment_signer_pubkey = ?commitment_signer_pubkey, "Validators and operator keys verified with Bolt Manager successfully" );