Skip to content

Commit

Permalink
Do the locking around Validator state instead of on each member
Browse files Browse the repository at this point in the history
  • Loading branch information
hrxi committed Nov 27, 2024
1 parent eca46dc commit 9e0e58e
Show file tree
Hide file tree
Showing 6 changed files with 170 additions and 184 deletions.
5 changes: 4 additions & 1 deletion client/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,10 @@ async fn main_inner() -> Result<(), Error> {
// Start validator
let val_metric_monitor = tokio_metrics::TaskMonitor::new();
if let Some(validator) = client.take_validator() {
info!("Initializing validator {}", validator.validator_address());
info!(
"Initializing validator {}",
validator.state().read().validator_address
);

if metrics_enabled {
let mp_metrics_monitor = validator.get_mempool_monitor();
Expand Down
12 changes: 6 additions & 6 deletions lib/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ use nimiq_validator::key_utils::VotingKeys;
#[cfg(feature = "validator")]
use nimiq_validator::validator::Validator as AbstractValidator;
#[cfg(feature = "validator")]
use nimiq_validator::validator::ValidatorProxy as AbstractValidatorProxy;
use nimiq_validator::validator::ValidatorState as AbstractValidatorState;
#[cfg(feature = "validator")]
use nimiq_validator_network::network_impl::ValidatorNetworkImpl;
#[cfg(feature = "wallet")]
Expand Down Expand Up @@ -72,7 +72,7 @@ pub type ConsensusProxy = AbstractConsensusProxy<Network>;
#[cfg(feature = "validator")]
pub type Validator = AbstractValidator<ValidatorNetworkImpl<Network>>;
#[cfg(feature = "validator")]
pub type ValidatorProxy = AbstractValidatorProxy;
pub type ValidatorState = AbstractValidatorState;

pub type ZKPComponent = AbstractZKPComponent<Network>;
pub type ZKPComponentProxy = AbstractZKPComponentProxy<Network>;
Expand Down Expand Up @@ -104,7 +104,7 @@ pub(crate) struct ClientInner {
blockchain: BlockchainProxy,

#[cfg(feature = "validator")]
validator: Option<ValidatorProxy>,
validator: Option<Arc<RwLock<ValidatorState>>>,

/// Wallet that stores key pairs for transaction signing
#[cfg(feature = "wallet")]
Expand Down Expand Up @@ -615,9 +615,9 @@ impl ClientInner {
blockchain.write().tx_verification_cache =
Arc::<Mempool>::clone(&validator.mempool_task.mempool);

let validator_proxy = validator.proxy();
let validator_state = Arc::clone(validator.state());
validator_or_mempool = Some(ValidatorOrMempool::Validator(validator));
Some(validator_proxy)
Some(validator_state)
} else {
None
}
Expand Down Expand Up @@ -768,7 +768,7 @@ impl Client {

#[cfg(feature = "validator")]
/// Returns a reference to the *Validator proxy*.
pub fn validator_proxy(&self) -> Option<ValidatorProxy> {
pub fn validator_proxy(&self) -> Option<Arc<RwLock<ValidatorState>>> {
self.inner.validator.clone()
}

Expand Down
35 changes: 21 additions & 14 deletions rpc-server/src/dispatchers/validator.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::sync::atomic::Ordering;
use std::{mem, sync::Arc};

use async_trait::async_trait;
use nimiq_bls::{KeyPair as BlsKeyPair, SecretKey as BlsSecretKey};
Expand All @@ -7,17 +7,18 @@ use nimiq_keys::Address;
use nimiq_network_libp2p::Network;
use nimiq_rpc_interface::{types::RPCResult, validator::ValidatorInterface};
use nimiq_serde::{Deserialize, Serialize};
use nimiq_validator::validator::ValidatorProxy;
use nimiq_validator::validator::ValidatorState;
use parking_lot::RwLock;

use crate::error::Error;

pub struct ValidatorDispatcher {
validator: ValidatorProxy,
validator: Arc<RwLock<ValidatorState>>,
consensus: ConsensusProxy<Network>,
}

impl ValidatorDispatcher {
pub fn new(validator: ValidatorProxy, consensus: ConsensusProxy<Network>) -> Self {
pub fn new(validator: Arc<RwLock<ValidatorState>>, consensus: ConsensusProxy<Network>) -> Self {
ValidatorDispatcher {
validator,
consensus,
Expand All @@ -31,18 +32,19 @@ impl ValidatorInterface for ValidatorDispatcher {
type Error = Error;

async fn get_address(&mut self) -> RPCResult<Address, (), Self::Error> {
Ok(self.validator.validator_address.read().clone().into())
Ok(self.validator.read().validator_address.clone().into())
}

// TODO: why do we give out secret keys via RPC?
async fn get_signing_key(&mut self) -> RPCResult<String, (), Self::Error> {
Ok(hex::encode(self.validator.signing_key.read().private.serialize_to_vec()).into())
Ok(hex::encode(self.validator.read().signing_key.private.serialize_to_vec()).into())
}

async fn get_voting_key(&mut self) -> RPCResult<String, (), Self::Error> {
Ok(hex::encode(
self.validator
.voting_keys
.read()
.voting_keys
.get_current_key()
.secret_key
.serialize_to_vec(),
Expand All @@ -53,8 +55,8 @@ impl ValidatorInterface for ValidatorDispatcher {
async fn get_voting_keys(&mut self) -> RPCResult<Vec<String>, (), Self::Error> {
Ok(self
.validator
.voting_keys
.read()
.voting_keys
.get_keys()
.into_iter()
.map(|key| hex::encode(key.secret_key.serialize_to_vec()))
Expand All @@ -63,7 +65,7 @@ impl ValidatorInterface for ValidatorDispatcher {
}

async fn add_voting_key(&mut self, secret_key: String) -> RPCResult<(), (), Self::Error> {
self.validator.voting_keys.write().add_key(BlsKeyPair::from(
self.validator.write().voting_keys.add_key(BlsKeyPair::from(
BlsSecretKey::deserialize_from_vec(&hex::decode(secret_key)?)?,
));
Ok(().into())
Expand All @@ -73,16 +75,21 @@ impl ValidatorInterface for ValidatorDispatcher {
&mut self,
automatic_reactivate: bool,
) -> RPCResult<(), (), Self::Error> {
self.validator
.automatic_reactivate
.store(automatic_reactivate, Ordering::Release);
let old = mem::replace(
&mut self.validator.write().automatic_reactivate,
automatic_reactivate,
);

log::debug!("Automatic reactivation set to {}.", automatic_reactivate);
log::debug!(
"Automatic reactivation set to {} (from {}).",
automatic_reactivate,
old
);
Ok(().into())
}

async fn is_validator_elected(&mut self) -> RPCResult<bool, (), Self::Error> {
let is_elected = self.validator.slot_band.read().is_some();
let is_elected = self.validator.read().slot_band.is_some();
Ok(is_elected.into())
}

Expand Down
16 changes: 14 additions & 2 deletions test-utils/src/validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,13 @@ where
validators
.iter()
.find(|validator| {
&validator.current_voting_key().public_key.compress()
&validator
.state()
.read()
.voting_keys
.get_current_key()
.public_key
.compress()
== slot.validator.voting_key.compressed()
})
.unwrap()
Expand All @@ -193,7 +199,13 @@ where
let index = validators
.iter()
.position(|validator| {
&validator.current_voting_key().public_key.compress()
&validator
.state()
.read()
.voting_keys
.get_current_key()
.public_key
.compress()
== slot.validator.voting_key.compressed()
})
.unwrap();
Expand Down
Loading

0 comments on commit 9e0e58e

Please sign in to comment.