From c016f48bb972fb0d1e555abfa8960844655e4fed Mon Sep 17 00:00:00 2001 From: Sebastian Date: Sat, 16 Nov 2024 13:33:17 -0600 Subject: [PATCH] Add basic key sanity checks. Don't produce blocks if keys don't match. --- blockchain/src/block_production/mod.rs | 14 +++++++++++++- validator/src/tendermint.rs | 12 ++++++++++++ validator/src/validator.rs | 26 +++++++++++++------------- 3 files changed, 38 insertions(+), 14 deletions(-) diff --git a/blockchain/src/block_production/mod.rs b/blockchain/src/block_production/mod.rs index 05188057ed..80a6f4249c 100644 --- a/blockchain/src/block_production/mod.rs +++ b/blockchain/src/block_production/mod.rs @@ -146,7 +146,7 @@ impl BlockProducer { let seed = if skip_block_proof.is_some() { // VRF seed of a skip block is carried over since a new VRF seed would require a new // leader. - prev_seed + prev_seed.clone() } else { prev_seed.sign_next_with_rng(&self.signing_key, block_number, rng) }; @@ -225,6 +225,18 @@ impl BlockProducer { let justification = if let Some(skip_block_proof) = skip_block_proof { MicroJustification::Skip(skip_block_proof) } else { + // Sanity check the signing key + let validators = blockchain + .current_validators() + .expect("current validators must be accessible."); + let epoch_validator = validators.get_validator_by_slot_number( + blockchain + .get_proposer(block_number, block_number, prev_seed.entropy(), None) + .expect("should find producer") + .number, + ); + assert_eq!(self.signing_key.public, epoch_validator.signing_key); + // Signs the block header using the signing key. let hash = header.hash(); let signature = self.signing_key.sign(hash.as_slice()); diff --git a/validator/src/tendermint.rs b/validator/src/tendermint.rs index 11efc3c75f..eadd9d3838 100644 --- a/validator/src/tendermint.rs +++ b/validator/src/tendermint.rs @@ -405,6 +405,18 @@ where id: id.clone(), }; + let one_of_our_slots = self + .validator_registry + .get_slots(self.validator_slot_band) + .start; + + let public_key = self + .validator_registry + .public_key(one_of_our_slots as usize) + .expect("Key must be be present"); + + assert_eq!(self.block_producer.voting_key.public_key, public_key); + let own_contribution = TendermintContribution::from_vote( tendermint_vote, &self.block_producer.voting_key.secret_key, diff --git a/validator/src/validator.rs b/validator/src/validator.rs index 3ade892a99..420a540870 100644 --- a/validator/src/validator.rs +++ b/validator/src/validator.rs @@ -342,6 +342,19 @@ where epoch_number = blockchain.epoch_number(), "We are ACTIVE in this epoch" ); + + // Find the entry for this validator in the epochs validators. + let epoch_validator = validators.get_validator_by_slot_band(slot_band); + + // Compare configured validator voting key to the one in the current epoch to make sure it is the same. + if *epoch_validator.voting_key.compressed() != self.voting_key().public_key.compress() { + panic!("Invalid validator configuration: Configured voting key does not match voting key in this epoch"); + } + + // Compare configured validator signing key to the one in the current epoch to make sure it is the same. + if epoch_validator.signing_key != self.signing_key().public { + panic!("Invalid validator configuration: Configured signing key does not match signing key in this epoch"); + } } else { log::debug!( validator_address = %self.validator_address(), @@ -355,19 +368,6 @@ where // Set the elected validators of the current epoch in the network as well. self.network.set_validators(validators); - - // Check validator configuration - if let Some(validator) = self.get_validator(&blockchain) { - // Compare configured validator voting key to the one in the contract to make sure it is the same. - if validator.voting_key != self.voting_key().public_key.compress() { - error!("Invalid validator configuration: Configured voting key does not match voting key in staking contract"); - } - - // Compare configured validator signing key to the one in the contract to make sure it is the same. - if validator.signing_key != self.signing_key().public { - error!("Invalid validator configuration: Configured signing key does not match signing key in staking contract"); - } - } } fn init_block_producer(&mut self, head_hash: Option<&Blake2bHash>) {