Repository: MystenLabs/sui
File: crates/sui-benchmark/src/lib.rs (Rust)

Code before:
                SubmitTransactionOptions::default(),
                Some(Duration::from_secs(60)),
            )
            .await?;
        Ok(ExecutionEffects::FinalizedTransactionEffects(
            response.effects,
            response.events.unwrap_or_default(),
        ))
    }

    /// Submit a transaction to multiple validators to cause consensus amplification.
    /// This is used to test the unpaid amplification deferral logic.
    pub async fn submit_transaction_with_amplification(
        &self,
        tx: Transaction,
        num_validators: usize,
    ) -> anyhow::Result<ExecutionEffects> {
        use sui_core::authority_client::AuthorityAPI;
        use sui_types::messages_grpc::SubmitTxRequest;

        // Submit to multiple validators in parallel
        let validators: Vec<_> = self.clients.values().take(num_validators).collect();
        let request = SubmitTxRequest::new_transaction(tx.clone());

        let futures: Vec<_> = validators
            .iter()
            .map(|client| {
                let req = request.clone();
                async move { client.submit_transaction(req, None).await }
            })
            .collect();

        // Fire off all submissions but don't wait for responses
        let _ = futures::future::join_all(futures).await;

        // Use the normal path to get the final result
        self.submit_transaction_block(tx).await
    }
}

#[async_trait]
impl ValidatorProxy for LocalValidatorAggregatorProxy {
    async fn get_sui_address_balance(&self, _: SuiAddress) -> Result<u64, anyhow::Error> {
        unimplemented!("Not available for LocalValidatorAggregatorProxy");
    }

    async fn get_object(&self, object_id: ObjectID) -> Result<Object, anyhow::Error> {
        let auth_agg = self.td.authority_aggregator().load();
        Ok(auth_agg
            .get_latest_object_version_for_testing(object_id)
            .await?)

Review comment (suggestion):
Probably specify that the `num_validators` designate additional validators (ex if `num_validators == 1` , then the transaction will eventually be submitted to two validators)

Code after:
        Self {
            td,
            clients,
            committee,
            chain_identifier,
            sui_client,
        }
    }

    // Submit transaction block using Transaction Driver
    async fn submit_transaction_block(&self, tx: Transaction) -> anyhow::Result<ExecutionEffects> {
        let response = self
            .td
            .drive_transaction(
                SubmitTxRequest::new_transaction(tx.clone()),
                SubmitTransactionOptions::default(),
                Some(Duration::from_secs(60)),
            )
            .await?;
        Ok(ExecutionEffects::FinalizedTransactionEffects(
            response.effects,
            response.events.unwrap_or_default(),
        ))
    }

    /// Submit a transaction to multiple validators to cause consensus amplification.
    /// This is used to test the unpaid amplification deferral logic.
    ///
    /// `num_validators` specifies how many additional validators to submit to beyond
    /// the normal submission path. For example, if `num_validators == 2`, the transaction
    /// will be submitted to 2 validators directly, plus once via the normal driver path.
    pub async fn submit_transaction_with_amplification(
        &self,
        tx: Transaction,
        num_validators: usize,
    ) -> anyhow::Result<ExecutionEffects> {
        use sui_core::authority_client::AuthorityAPI;
        use sui_types::messages_grpc::SubmitTxRequest;

        // Submit to multiple validators in parallel
        let validators: Vec<_> = self.clients.values().take(num_validators).collect();
        let request = SubmitTxRequest::new_transaction(tx.clone());

        let futures: Vec<_> = validators
            .iter()
            .map(|client| {
                let req = request.clone();
                async move { client.submit_transaction(req, None).await }
            })
            .collect();