Skip to content

Commit

Permalink
Adding a benchmark for transaction signing (#14174)
Browse files Browse the repository at this point in the history
## Description 
Adding a benchmark to measure validator signing transaction performace
in the single node benchmark suite.

Sample output:

```
cargo run --release --bin sui-single-node-benchmark -- move --component txn-signing

2023-10-10T16:08:05.023632Z  INFO sui_single_node_benchmark::benchmark_context: Creating 500001 accounts and 1000002 gas objects
2023-10-10T16:08:06.430838Z  INFO sui_single_node_benchmark::benchmark_context: Initializing validator
2023-10-10T16:08:10.306098Z  INFO sui_single_node_benchmark::benchmark_context: Programmable Move Transaction Generator: Creating 500001 transactions
2023-10-10T16:08:11.236391Z  INFO sui_single_node_benchmark::execution: Sample transaction: SenderSignedData([SenderSignedTransaction { intent_message: IntentMessage { intent: Intent { scope: TransactionData, version: V0, app_id: Sui }, value: V1(TransactionDataV1 { kind: ProgrammableTransaction(ProgrammableTransaction { inputs: [Object(ImmOrOwnedObject((0xff01000000000000000000000000000000000000000000000000000000000000, SequenceNumber(1), o#3Wy9EiapZQKhT8rAyQMyrNNYY16hUSJdqhwetB92C4pu))), Pure([184, 159, 82, 182, 144, 220, 83, 194, 8, 51, 15, 138, 44, 214, 190, 240, 85, 19, 16, 201, 173, 213, 246, 216, 58, 70, 65, 252, 110, 209, 66, 161]), Pure([0, 0, 0, 0, 0, 0, 0, 0])], commands: [MakeMoveVec(None, [Input(0)]), MoveCall(ProgrammableMoveCall { package: 0x22b99c7c24f1fe4e0ba3a3b65b120f85fc3923fcf9111ddc75caa54150604920, module: Identifier("benchmark"), function: Identifier("merge_input_coins"), type_arguments: [], arguments: [Result(0)] }), TransferObjects([Result(1)], Input(1)), MoveCall(ProgrammableMoveCall { package: 0x22b99c7c24f1fe4e0ba3a3b65b120f85fc3923fcf9111ddc75caa54150604920, module: Identifier("benchmark"), function: Identifier("run_computation"), type_arguments: [], arguments: [Input(2)] })] }), sender: 0xb89f52b690dc53c208330f8a2cd6bef0551310c9add5f6d83a4641fc6ed142a1, gas_data: GasData { payment: [(0xff00000000000000000000000000000000000000000000000000000000000000, SequenceNumber(1), o#9tCQKCfifCQzaicSPdBpWyPKVD6fJFcKatKoHn9TyBEn)], owner: 0xb89f52b690dc53c208330f8a2cd6bef0551310c9add5f6d83a4641fc6ed142a1, price: 1000, budget: 5000000000 }, expiration: None }) }, tx_signatures: [Signature(Ed25519SuiSignature(Ed25519SuiSignature([0, 124, 197, 41, 122, 155, 114, 67, 77, 13, 124, 161, 104, 88, 199, 110, 40, 181, 128, 92, 5, 144, 52, 28, 230, 159, 225, 27, 88, 94, 74, 10, 49, 189, 110, 178, 7, 46, 169, 154, 72, 167, 128, 132, 104, 166, 96, 142, 46, 92, 11, 217, 238, 201, 121, 206, 109, 215, 229, 219, 52, 157, 237, 154, 4, 98, 34, 97, 21, 172, 104, 110, 152, 8, 19, 17, 185, 26, 203, 149, 57, 52, 64, 167, 160, 214, 216, 121, 224, 126, 86, 237, 26, 8, 57, 116, 90])))] }])
2023-10-10T16:08:11.236431Z  INFO sui_single_node_benchmark::benchmark_context: Started signing 500001 transactions. You can now attach a profiler
2023-10-10T16:08:23.669227Z  INFO sui_single_node_benchmark::execution: Transaction signing finished in 12.432s, TPS=40218.87065637066
```

## Test Plan 

How did you test the new or updated feature?

---
If your changes are not user-facing and not a breaking change, you can
skip the following section. Otherwise, please indicate what changed, and
then add to the Release Notes section as highlighted during the release
process.

### Type of Change (Check all that apply)

- [ ] protocol change
- [ ] user-visible impact
- [ ] breaking change for a client SDKs
- [ ] breaking change for FNs (FN binary must upgrade)
- [ ] breaking change for validators or node operators (must upgrade
binaries)
- [ ] breaking change for on-chain data layout
- [ ] necessitate either a data wipe or data migration

### Release notes

---------

Co-authored-by: Zhe Wu <[email protected]>
  • Loading branch information
halfprice and Zhe Wu authored Oct 11, 2023
1 parent 8b0276c commit fe2bd7f
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 3 deletions.
10 changes: 10 additions & 0 deletions crates/sui-core/src/authority_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,16 @@ impl ValidatorService {
.into_inner()
}

pub async fn handle_transaction_for_testing(
&self,
transaction: Transaction,
) -> HandleTransactionResponse {
self.transaction(tonic::Request::new(transaction))
.await
.unwrap()
.into_inner()
}

async fn handle_transaction(
self,
request: tonic::Request<Transaction>,
Expand Down
20 changes: 20 additions & 0 deletions crates/sui-single-node-benchmark/src/benchmark_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use std::sync::Arc;
use sui_types::base_types::{ObjectID, ObjectRef, SuiAddress, SUI_ADDRESS_LENGTH};
use sui_types::crypto::{get_account_key_pair, AccountKeyPair};
use sui_types::effects::TransactionEffects;
use sui_types::messages_grpc::HandleTransactionResponse;
use sui_types::object::Object;
use sui_types::transaction::{CertifiedTransaction, SignedTransaction, Transaction};
use tracing::info;
Expand Down Expand Up @@ -232,4 +233,23 @@ impl BenchmarkContext {
*gas_objects = Arc::new(refreshed_gas_objects);
}
}

pub(crate) async fn validator_sign_transactions(
&self,
transactions: Vec<Transaction>,
) -> Vec<HandleTransactionResponse> {
info!(
"Started signing {} transactions. You can now attach a profiler",
transactions.len(),
);
let tasks: FuturesUnordered<_> = transactions
.into_iter()
.map(|tx| {
let validator = self.validator();
tokio::spawn(async move { validator.sign_transaction(tx).await })
})
.collect();
let results: Vec<_> = tasks.collect().await;
results.into_iter().map(|r| r.unwrap()).collect()
}
}
2 changes: 2 additions & 0 deletions crates/sui-single-node-benchmark/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,6 @@ pub enum Component {
/// and store the sequenced transactions into the store. It covers the consensus-independent
/// portion of the code in consensus handler.
ValidatorWithFakeConsensus,
/// Benchmark only validator signing compoment: `handle_transaction`.
TxnSigning,
}
37 changes: 34 additions & 3 deletions crates/sui-single-node-benchmark/src/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub async fn benchmark_simple_transfer(tx_count: u64, component: Component) {
let transactions = ctx
.generate_transactions(Arc::new(NonMoveTxGenerator::new()))
.await;
benchmark_transactions(&ctx, transactions).await;
benchmark_transactions(&ctx, transactions, component).await;
}

/// Benchmark Move transactions.
Expand Down Expand Up @@ -57,7 +57,7 @@ pub async fn benchmark_move_transactions(
root_objects,
)))
.await;
benchmark_transactions(&ctx, transactions).await;
benchmark_transactions(&ctx, transactions, component).await;
}

/// In order to benchmark transactions that can read dynamic fields, we must first create
Expand Down Expand Up @@ -104,8 +104,23 @@ async fn preparing_dynamic_fields(
root_objects
}

async fn benchmark_transactions(
ctx: &BenchmarkContext,
transactions: Vec<Transaction>,
component: Component,
) {
match component {
Component::TxnSigning => {
benchmark_transaction_signing(ctx, transactions).await;
}
_ => {
benchmark_transaction_execution(ctx, transactions).await;
}
}
}

/// Benchmark parallel execution of a vector of transactions and measure the TPS.
async fn benchmark_transactions(ctx: &BenchmarkContext, transactions: Vec<Transaction>) {
async fn benchmark_transaction_execution(ctx: &BenchmarkContext, transactions: Vec<Transaction>) {
let mut transactions = ctx.certify_transactions(transactions).await;

// Print out a sample transaction and its effects so that we can get a rough idea
Expand All @@ -129,3 +144,19 @@ async fn benchmark_transactions(ctx: &BenchmarkContext, transactions: Vec<Transa
tx_count as f64 / elapsed
);
}

/// Benchmark parallel signing a vector of transactions and measure the TPS.
async fn benchmark_transaction_signing(ctx: &BenchmarkContext, transactions: Vec<Transaction>) {
let sample_transaction = &transactions[0];
info!("Sample transaction: {:?}", sample_transaction.data());

let tx_count = transactions.len();
let start_time = std::time::Instant::now();
ctx.validator_sign_transactions(transactions).await;
let elapsed = start_time.elapsed().as_millis() as f64 / 1000f64;
info!(
"Transaction signing finished in {}s, TPS={}.",
elapsed,
tx_count as f64 / elapsed,
);
}
9 changes: 9 additions & 0 deletions crates/sui-single-node-benchmark/src/single_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use sui_types::committee::Committee;
use sui_types::crypto::AccountKeyPair;
use sui_types::effects::{TransactionEffects, TransactionEffectsAPI};
use sui_types::executable_transaction::VerifiedExecutableTransaction;
use sui_types::messages_grpc::HandleTransactionResponse;
use sui_types::object::Object;
use sui_types::transaction::{
CertifiedTransaction, Transaction, VerifiedCertificate, VerifiedTransaction,
Expand Down Expand Up @@ -115,6 +116,7 @@ impl SingleValidator {
cert: CertifiedTransaction,
component: Component,
) -> TransactionEffects {
assert!(!matches!(component, Component::TxnSigning));
let effects = match component {
Component::Baseline => {
let cert = VerifiedExecutableTransaction::new_from_certificate(
Expand Down Expand Up @@ -142,8 +144,15 @@ impl SingleValidator {
.await;
response.signed_effects.into_data()
}
Component::TxnSigning => unreachable!(),
};
assert!(effects.status().is_ok());
effects
}

pub async fn sign_transaction(&self, transaction: Transaction) -> HandleTransactionResponse {
self.validator_service
.handle_transaction_for_testing(transaction)
.await
}
}

1 comment on commit fe2bd7f

@vercel
Copy link

@vercel vercel bot commented on fe2bd7f Oct 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.