Skip to content

Commit

Permalink
[stress test] Bypass signature verification (MystenLabs#8803)
Browse files Browse the repository at this point in the history
Stress client can generate low tps, because quorum driver verifies
individual signatures from each validator.

To handle this we made a `BENCH_MODE`, which has custom logic instead of
quorum driver, but it does not seem to work well.

This PR uses quorum driver in stress test, but bypass signature
verification in the quorum driver itself
  • Loading branch information
andll authored Mar 3, 2023
1 parent 4f61788 commit 023ad7f
Show file tree
Hide file tree
Showing 11 changed files with 150 additions and 77 deletions.
15 changes: 9 additions & 6 deletions crates/sui-benchmark/src/embedded_reconfig_observer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use anyhow::anyhow;
use async_trait::async_trait;
use std::sync::Arc;
use sui_core::authority_aggregator::AuthorityAggregator;
use sui_core::signature_verifier::SignatureVerifier;
use sui_core::{
authority_client::NetworkAuthorityClient,
quorum_driver::{reconfig_observer::ReconfigObserver, QuorumDriver},
Expand Down Expand Up @@ -34,10 +35,10 @@ impl EmbeddedReconfigObserver {
}

impl EmbeddedReconfigObserver {
pub async fn get_committee(
pub async fn get_committee<S: SignatureVerifier + Default>(
&self,
auth_agg: Arc<AuthorityAggregator<NetworkAuthorityClient>>,
) -> anyhow::Result<Arc<AuthorityAggregator<NetworkAuthorityClient>>> {
auth_agg: Arc<AuthorityAggregator<NetworkAuthorityClient, S>>,
) -> anyhow::Result<Arc<AuthorityAggregator<NetworkAuthorityClient, S>>> {
// auth_agg and cur_epoch is consistently in each iteration,
// assuming no other ReconfigObserver is working at the same time.
let cur_epoch = auth_agg.committee.epoch();
Expand Down Expand Up @@ -72,12 +73,14 @@ impl EmbeddedReconfigObserver {
}

#[async_trait]
impl ReconfigObserver<NetworkAuthorityClient> for EmbeddedReconfigObserver {
fn clone_boxed(&self) -> Box<dyn ReconfigObserver<NetworkAuthorityClient> + Send + Sync> {
impl<S: SignatureVerifier + Default> ReconfigObserver<NetworkAuthorityClient, S>
for EmbeddedReconfigObserver
{
fn clone_boxed(&self) -> Box<dyn ReconfigObserver<NetworkAuthorityClient, S> + Send + Sync> {
Box::new(self.clone())
}

async fn run(&mut self, quorum_driver: Arc<QuorumDriver<NetworkAuthorityClient>>) {
async fn run(&mut self, quorum_driver: Arc<QuorumDriver<NetworkAuthorityClient, S>>) {
loop {
tokio::time::sleep(tokio::time::Duration::from_secs(5)).await;
let auth_agg = quorum_driver.authority_aggregator().load();
Expand Down
9 changes: 6 additions & 3 deletions crates/sui-benchmark/src/fullnode_reconfig_observer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use async_trait::async_trait;
use std::collections::BTreeMap;
use std::sync::Arc;
use sui_core::signature_verifier::SignatureVerifier;
use sui_core::{
authority_aggregator::{AuthAggMetrics, AuthorityAggregator},
authority_client::NetworkAuthorityClient,
Expand Down Expand Up @@ -53,12 +54,14 @@ impl FullNodeReconfigObserver {
}

#[async_trait]
impl ReconfigObserver<NetworkAuthorityClient> for FullNodeReconfigObserver {
fn clone_boxed(&self) -> Box<dyn ReconfigObserver<NetworkAuthorityClient> + Send + Sync> {
impl<S: SignatureVerifier + Default> ReconfigObserver<NetworkAuthorityClient, S>
for FullNodeReconfigObserver
{
fn clone_boxed(&self) -> Box<dyn ReconfigObserver<NetworkAuthorityClient, S> + Send + Sync> {
Box::new(self.clone())
}

async fn run(&mut self, quorum_driver: Arc<QuorumDriver<NetworkAuthorityClient>>) {
async fn run(&mut self, quorum_driver: Arc<QuorumDriver<NetworkAuthorityClient, S>>) {
loop {
tokio::time::sleep(tokio::time::Duration::from_secs(3)).await;
match self.fullnode_client.read_api().get_sui_system_state().await {
Expand Down
8 changes: 5 additions & 3 deletions crates/sui-benchmark/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use std::{
};
use sui_config::genesis::Genesis;
use sui_config::NetworkConfig;
use sui_core::signature_verifier::IgnoreSignatureVerifier;
use sui_core::{
authority_aggregator::{AuthorityAggregator, AuthorityAggregatorBuilder},
authority_client::{make_authority_clients, AuthorityAPI, NetworkAuthorityClient},
Expand Down Expand Up @@ -140,8 +141,9 @@ pub trait ValidatorProxy {

// TODO: Eventually remove this proxy because we shouldn't rely on validators to read objects.
pub struct LocalValidatorAggregatorProxy {
_qd_handler: QuorumDriverHandler<NetworkAuthorityClient>,
qd: Arc<QuorumDriver<NetworkAuthorityClient>>,
_qd_handler: QuorumDriverHandler<NetworkAuthorityClient, IgnoreSignatureVerifier>,
// Stress client does not verify individual validator signatures since this is very expensive
qd: Arc<QuorumDriver<NetworkAuthorityClient, IgnoreSignatureVerifier>>,
committee: Committee,
clients: BTreeMap<AuthorityName, NetworkAuthorityClient>,
requests: Mutex<JoinSet<()>>,
Expand Down Expand Up @@ -205,7 +207,7 @@ impl LocalValidatorAggregatorProxy {
}

async fn new_impl(
aggregator: AuthorityAggregator<NetworkAuthorityClient>,
aggregator: AuthorityAggregator<NetworkAuthorityClient, IgnoreSignatureVerifier>,
registry: &Registry,
reconfig_fullnode_rpc_url: Option<&str>,
clients: BTreeMap<AuthorityName, NetworkAuthorityClient>,
Expand Down
37 changes: 22 additions & 15 deletions crates/sui-core/src/authority_aggregator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ use tokio::time::{sleep, timeout};

use crate::authority::AuthorityStore;
use crate::epoch::committee_store::CommitteeStore;
use crate::signature_verifier::{DefaultSignatureVerifier, SignatureVerifier};
use crate::stake_aggregator::{InsertResult, MultiStakeAggregator, StakeAggregator};

pub const DEFAULT_RETRIES: usize = 4;
Expand Down Expand Up @@ -236,11 +237,11 @@ impl ProcessTransactionResult {
}

#[derive(Clone)]
pub struct AuthorityAggregator<A> {
pub struct AuthorityAggregator<A, S = DefaultSignatureVerifier> {
/// Our Sui committee.
pub committee: Committee,
/// How to talk to this committee.
pub authority_clients: BTreeMap<AuthorityName, SafeClient<A>>,
pub authority_clients: BTreeMap<AuthorityName, SafeClient<A, S>>,
/// Metrics
pub metrics: AuthAggMetrics,
/// Metric base for the purpose of creating new safe clients during reconfiguration.
Expand All @@ -250,7 +251,7 @@ pub struct AuthorityAggregator<A> {
pub committee_store: Arc<CommitteeStore>,
}

impl<A> AuthorityAggregator<A> {
impl<A, S: SignatureVerifier + Default> AuthorityAggregator<A, S> {
pub fn new(
committee: Committee,
committee_store: Arc<CommitteeStore>,
Expand Down Expand Up @@ -338,7 +339,7 @@ impl<A> AuthorityAggregator<A> {
committee: CommitteeWithNetAddresses,
network_config: &Config,
disallow_missing_intermediate_committees: bool,
) -> SuiResult<AuthorityAggregator<NetworkAuthorityClient>> {
) -> SuiResult<AuthorityAggregator<NetworkAuthorityClient, S>> {
let network_clients =
make_network_authority_client_sets_from_committee(&committee, network_config).map_err(
|err| SuiError::GenericAuthorityError {
Expand Down Expand Up @@ -394,11 +395,11 @@ impl<A> AuthorityAggregator<A> {
})
}

pub fn get_client(&self, name: &AuthorityName) -> Option<&SafeClient<A>> {
pub fn get_client(&self, name: &AuthorityName) -> Option<&SafeClient<A, S>> {
self.authority_clients.get(name)
}

pub fn clone_client(&self, name: &AuthorityName) -> SafeClient<A>
pub fn clone_client(&self, name: &AuthorityName) -> SafeClient<A, S>
where
A: Clone,
{
Expand All @@ -421,7 +422,7 @@ impl<A> AuthorityAggregator<A> {
}
}

impl AuthorityAggregator<NetworkAuthorityClient> {
impl<S: SignatureVerifier + Default> AuthorityAggregator<NetworkAuthorityClient, S> {
/// Create a new network authority aggregator by reading the committee and
/// network address information from the system state object on-chain.
/// This function needs metrics parameters because registry will panic
Expand Down Expand Up @@ -470,7 +471,7 @@ pub enum ReduceOutput<R, S> {
Success(R),
}

impl<A> AuthorityAggregator<A>
impl<A, SV: SignatureVerifier + Default> AuthorityAggregator<A, SV>
where
A: AuthorityAPI + Send + Sync + 'static + Clone,
{
Expand Down Expand Up @@ -503,7 +504,7 @@ where
initial_timeout: Duration,
) -> Result<R, S>
where
FMap: FnOnce(AuthorityName, &'a SafeClient<A>) -> AsyncResult<'a, V, SuiError> + Clone,
FMap: FnOnce(AuthorityName, &'a SafeClient<A, SV>) -> AsyncResult<'a, V, SuiError> + Clone,
FReduce: Fn(
S,
AuthorityName,
Expand All @@ -530,7 +531,7 @@ where
initial_timeout: Duration,
) -> Result<R, S>
where
FMap: FnOnce(AuthorityName, &'a SafeClient<A>) -> AsyncResult<'a, V, SuiError> + Clone,
FMap: FnOnce(AuthorityName, &'a SafeClient<A, SV>) -> AsyncResult<'a, V, SuiError> + Clone,
FReduce: Fn(
S,
AuthorityName,
Expand Down Expand Up @@ -605,7 +606,10 @@ where
authority_errors: &mut HashMap<AuthorityName, SuiError>,
) -> Result<S, SuiError>
where
FMap: Fn(AuthorityName, SafeClient<A>) -> AsyncResult<'a, S, SuiError> + Send + Clone + 'a,
FMap: Fn(AuthorityName, SafeClient<A, SV>) -> AsyncResult<'a, S, SuiError>
+ Send
+ Clone
+ 'a,
S: Send,
{
let start = tokio::time::Instant::now();
Expand All @@ -623,7 +627,7 @@ where

let mut futures = FuturesUnordered::<BoxFuture<'a, Event<S>>>::new();

let start_req = |name: AuthorityName, client: SafeClient<A>| {
let start_req = |name: AuthorityName, client: SafeClient<A, SV>| {
let map_each_authority = map_each_authority.clone();
Box::pin(monitored_future!(async move {
trace!(name=?name.concise(), now = ?tokio::time::Instant::now() - start, "new request");
Expand Down Expand Up @@ -738,7 +742,10 @@ where
description: String,
) -> Result<S, SuiError>
where
FMap: Fn(AuthorityName, SafeClient<A>) -> AsyncResult<'a, S, SuiError> + Send + Clone + 'a,
FMap: Fn(AuthorityName, SafeClient<A, SV>) -> AsyncResult<'a, S, SuiError>
+ Send
+ Clone
+ 'a,
S: Send,
{
let mut authority_errors = HashMap::new();
Expand Down Expand Up @@ -1352,10 +1359,10 @@ impl<'a> AuthorityAggregatorBuilder<'a> {
self
}

pub fn build(
pub fn build<S: SignatureVerifier + Default>(
self,
) -> anyhow::Result<(
AuthorityAggregator<NetworkAuthorityClient>,
AuthorityAggregator<NetworkAuthorityClient, S>,
BTreeMap<AuthorityPublicKeyBytes, NetworkAuthorityClient>,
)> {
let validator_info = if let Some(network_config) = self.network_config {
Expand Down
1 change: 1 addition & 0 deletions crates/sui-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub mod validator_info;
#[cfg(test)]
#[path = "unit_tests/pay_sui_tests.rs"]
mod pay_sui_tests;
pub mod signature_verifier;
pub mod test_authority_clients;

pub const SUI_CORE_VERSION: &str = env!("CARGO_PKG_VERSION");
Loading

0 comments on commit 023ad7f

Please sign in to comment.