Skip to content

Commit

Permalink
separate Epoch related errors in authority_aggregator.handle_transact…
Browse files Browse the repository at this point in the history
…ion (MystenLabs#7003)

Meat is in `authority_aggregator.rs`. Currently we mix errors with wrong
epoch and others such as validator returns an invalid response due to
data corruption. This PR separates the errors and add tests.
Also moving `LocalAuthorityClient` and `MockAuthorityApi` into a new
test-only file.
  • Loading branch information
longbowlu authored Jan 5, 2023
1 parent a79128e commit 5fb51ac
Show file tree
Hide file tree
Showing 10 changed files with 830 additions and 393 deletions.
233 changes: 133 additions & 100 deletions crates/sui-core/src/authority_aggregator.rs

Large diffs are not rendered by default.

169 changes: 0 additions & 169 deletions crates/sui-core/src/authority_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

use crate::authority::AuthorityState;
use anyhow::anyhow;
use async_trait::async_trait;
use fastcrypto::traits::ToFromBytes;
use multiaddr::Multiaddr;
use mysten_metrics::spawn_monitored_task;
use mysten_network::config::Config;
use std::collections::BTreeMap;
use std::sync::Arc;
use std::time::Duration;
use sui_config::genesis::Genesis;
use sui_config::ValidatorInfo;
Expand All @@ -20,7 +17,6 @@ use sui_types::committee::CommitteeWithNetAddresses;
use sui_types::crypto::AuthorityPublicKeyBytes;
use sui_types::messages_checkpoint::{CheckpointRequest, CheckpointResponse};
use sui_types::sui_system_state::SuiSystemState;
use sui_types::{committee::Committee, crypto::AuthorityKeyPair, object::Object};
use sui_types::{error::SuiError, messages::*};

use sui_network::tonic::transport::Channel;
Expand Down Expand Up @@ -254,168 +250,3 @@ pub fn make_authority_clients(
}
authority_clients
}

#[derive(Clone, Copy, Default)]
pub struct LocalAuthorityClientFaultConfig {
pub fail_before_handle_transaction: bool,
pub fail_after_handle_transaction: bool,
pub fail_before_handle_confirmation: bool,
pub fail_after_handle_confirmation: bool,
}

impl LocalAuthorityClientFaultConfig {
pub fn reset(&mut self) {
*self = Self::default();
}
}

#[derive(Clone)]
pub struct LocalAuthorityClient {
pub state: Arc<AuthorityState>,
pub fault_config: LocalAuthorityClientFaultConfig,
}

#[async_trait]
impl AuthorityAPI for LocalAuthorityClient {
async fn handle_transaction(
&self,
transaction: Transaction,
) -> Result<TransactionInfoResponse, SuiError> {
if self.fault_config.fail_before_handle_transaction {
return Err(SuiError::from("Mock error before handle_transaction"));
}
let state = self.state.clone();
let transaction = transaction.verify()?;
let result = state.handle_transaction(transaction).await;
if self.fault_config.fail_after_handle_transaction {
return Err(SuiError::GenericAuthorityError {
error: "Mock error after handle_transaction".to_owned(),
});
}
result.map(|r| r.into())
}

async fn handle_certificate(
&self,
certificate: CertifiedTransaction,
) -> Result<HandleCertificateResponse, SuiError> {
let state = self.state.clone();
let fault_config = self.fault_config;
spawn_monitored_task!(Self::handle_certificate(state, certificate, fault_config))
.await
.unwrap()
}

async fn handle_account_info_request(
&self,
request: AccountInfoRequest,
) -> Result<AccountInfoResponse, SuiError> {
let state = self.state.clone();
state.handle_account_info_request(request).await
}

async fn handle_object_info_request(
&self,
request: ObjectInfoRequest,
) -> Result<ObjectInfoResponse, SuiError> {
let state = self.state.clone();
state
.handle_object_info_request(request)
.await
.map(|r| r.into())
}

/// Handle Object information requests for this account.
async fn handle_transaction_info_request(
&self,
request: TransactionInfoRequest,
) -> Result<TransactionInfoResponse, SuiError> {
let state = self.state.clone();
state
.handle_transaction_info_request(request)
.await
.map(|r| r.into())
}

async fn handle_checkpoint(
&self,
request: CheckpointRequest,
) -> Result<CheckpointResponse, SuiError> {
let state = self.state.clone();

state.handle_checkpoint_request(&request)
}

async fn handle_committee_info_request(
&self,
request: CommitteeInfoRequest,
) -> Result<CommitteeInfoResponse, SuiError> {
let state = self.state.clone();

state.handle_committee_info_request(&request)
}
}

impl LocalAuthorityClient {
pub async fn new(committee: Committee, secret: AuthorityKeyPair, genesis: &Genesis) -> Self {
let state = AuthorityState::new_for_testing(committee, &secret, None, Some(genesis)).await;
Self {
state,
fault_config: LocalAuthorityClientFaultConfig::default(),
}
}

pub async fn new_with_objects(
committee: Committee,
secret: AuthorityKeyPair,
objects: Vec<Object>,
genesis: &Genesis,
) -> Self {
let client = Self::new(committee, secret, genesis).await;

for object in objects {
client.state.insert_genesis_object(object).await;
}

client
}

pub fn new_from_authority(state: Arc<AuthorityState>) -> Self {
Self {
state,
fault_config: LocalAuthorityClientFaultConfig::default(),
}
}

async fn handle_certificate(
state: Arc<AuthorityState>,
certificate: CertifiedTransaction,
fault_config: LocalAuthorityClientFaultConfig,
) -> Result<HandleCertificateResponse, SuiError> {
if fault_config.fail_before_handle_confirmation {
return Err(SuiError::GenericAuthorityError {
error: "Mock error before handle_confirmation_transaction".to_owned(),
});
}
// Check existing effects before verifying the cert to allow querying certs finalized
// from previous epochs.
let tx_digest = *certificate.digest();
let epoch_store = state.epoch_store();
let signed_effects =
match state.get_signed_effects_and_maybe_resign(epoch_store.epoch(), &tx_digest) {
Ok(Some(effects)) => effects,
_ => {
let certificate = { certificate.verify(epoch_store.committee())? };
state
.try_execute_immediately(&certificate, &epoch_store)
.await?
}
};
if fault_config.fail_after_handle_confirmation {
return Err(SuiError::GenericAuthorityError {
error: "Mock error after handle_confirmation_transaction".to_owned(),
});
}
Ok(HandleCertificateResponse { signed_effects })
}
}
1 change: 1 addition & 0 deletions crates/sui-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,6 @@ pub mod validator_info;
#[cfg(test)]
#[path = "unit_tests/pay_sui_tests.rs"]
mod pay_sui_tests;
pub mod test_authority_clients;

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

0 comments on commit 5fb51ac

Please sign in to comment.