diff --git a/tools/integration_bench/src/harness.rs b/tools/integration_bench/src/harness.rs index b00351b9..9337f3ed 100644 --- a/tools/integration_bench/src/harness.rs +++ b/tools/integration_bench/src/harness.rs @@ -77,12 +77,29 @@ impl ScenarioOutput { self.total = self.total.saturating_add(step.total); self.steps.push(step); } + + /// Run a single timed step against `ctx`: capture pre-block, run `submit`, + /// finalize timings, push a `StepResult` onto `self.steps`. Returns the + /// `SubcommandReturnValue` from `submit` so the caller can match on it. + pub async fn step( + &mut self, + ctx: &mut TestContext, + label: impl Into, + submit: impl AsyncFnOnce(&mut TestContext) -> Result, + ) -> Result { + let pre_block = begin_step(ctx).await?; + let started = Instant::now(); + let ret = submit(ctx).await?; + let step = finalize_step(label, started, pre_block, &ret, ctx).await?; + self.push(step); + Ok(ret) + } } /// Begin a timed step. Capture this *before* submitting the wallet operation /// so we can later subtract it from the post-submit block height to detect /// when the chain has advanced past the tx's block. -pub async fn begin_step(ctx: &TestContext) -> Result { +async fn begin_step(ctx: &TestContext) -> Result { Ok(ctx.sequencer_client().get_last_block_id().await?) } @@ -90,14 +107,7 @@ pub async fn begin_step(ctx: &TestContext) -> Result { /// being captured and `ret` being received) and, if `ret` is a /// [`SubcommandReturnValue::PrivacyPreservingTransfer`], polls the sequencer /// for inclusion and records the inclusion latency. Returns a [`StepResult`]. -/// -/// Usage: -/// ```ignore -/// let started = Instant::now(); -/// let ret = wallet::cli::execute_subcommand(ctx.wallet_mut(), cmd).await?; -/// let step = finalize_step("label", started, pre_block_id, &ret, ctx).await?; -/// ``` -pub async fn finalize_step( +async fn finalize_step( label: impl Into, started: Instant, pre_block_id: u64, diff --git a/tools/integration_bench/src/main.rs b/tools/integration_bench/src/main.rs index b218a087..ccf7058e 100644 --- a/tools/integration_bench/src/main.rs +++ b/tools/integration_bench/src/main.rs @@ -22,10 +22,12 @@ clippy::arithmetic_side_effects, clippy::print_stderr, clippy::print_stdout, + clippy::shadow_unrelated, clippy::wildcard_enum_match_arm, reason = "Bench tool: stderr/stdout output is the deliverable; small Duration / iterator-sum \ arithmetic is safe at bench scale; bench scenarios bail loudly on any unexpected \ - return variant, which is preferable to maintaining an exhaustive list in five files." + return variant, which is preferable to maintaining an exhaustive list in five files; \ + the step() closure helper canonically rebinds `ctx` inside the closure body." )] use std::{path::PathBuf, time::Duration}; diff --git a/tools/integration_bench/src/scenarios/amm.rs b/tools/integration_bench/src/scenarios/amm.rs index d0ddd6f0..f05eed1a 100644 --- a/tools/integration_bench/src/scenarios/amm.rs +++ b/tools/integration_bench/src/scenarios/amm.rs @@ -1,18 +1,16 @@ //! AMM swap flow: setup two tokens, create pool, swap, add liquidity, remove liquidity. -use std::time::Instant; - use anyhow::{Result, bail}; -use test_fixtures::public_mention; +use test_fixtures::{TestContext, public_mention}; use wallet::cli::{ Command, SubcommandReturnValue, account::{AccountSubcommand, NewSubcommand}, programs::{amm::AmmProgramAgnosticSubcommand, token::TokenProgramAgnosticSubcommand}, }; -use crate::harness::{ScenarioOutput, finalize_step}; +use crate::harness::ScenarioOutput; -pub async fn run(ctx: &mut test_fixtures::TestContext) -> Result { +pub async fn run(ctx: &mut TestContext) -> Result { let mut output = ScenarioOutput::new("amm_swap_flow"); let def_a = new_public_account(ctx, &mut output, "create_acc_def_a").await?; @@ -26,121 +24,97 @@ pub async fn run(ctx: &mut test_fixtures::TestContext) -> Result let user_lp = new_public_account(ctx, &mut output, "create_acc_user_lp").await?; timed_token_new(ctx, &mut output, "token_a_new", def_a, supply_a, "TokA").await?; - timed_token_send( - ctx, - &mut output, - "token_a_fund_user", - supply_a, - user_a, - 1_000, - ) - .await?; + timed_token_send(ctx, &mut output, "token_a_fund_user", supply_a, user_a, 1_000).await?; timed_token_new(ctx, &mut output, "token_b_new", def_b, supply_b, "TokB").await?; - timed_token_send( - ctx, - &mut output, - "token_b_fund_user", - supply_b, - user_b, - 1_000, - ) - .await?; + timed_token_send(ctx, &mut output, "token_b_fund_user", supply_b, user_b, 1_000).await?; - { - let pre_block = crate::harness::begin_step(ctx).await?; - let started = Instant::now(); - let ret = wallet::cli::execute_subcommand( - ctx.wallet_mut(), - Command::AMM(AmmProgramAgnosticSubcommand::New { - user_holding_a: public_mention(user_a), - user_holding_b: public_mention(user_b), - user_holding_lp: public_mention(user_lp), - balance_a: 300, - balance_b: 300, - }), - ) + output + .step(ctx, "amm_new_pool", async |ctx| { + wallet::cli::execute_subcommand( + ctx.wallet_mut(), + Command::AMM(AmmProgramAgnosticSubcommand::New { + user_holding_a: public_mention(user_a), + user_holding_b: public_mention(user_b), + user_holding_lp: public_mention(user_lp), + balance_a: 300, + balance_b: 300, + }), + ) + .await + }) .await?; - let step = finalize_step("amm_new_pool", started, pre_block, &ret, ctx).await?; - output.push(step); - } - { - let pre_block = crate::harness::begin_step(ctx).await?; - let started = Instant::now(); - let ret = wallet::cli::execute_subcommand( - ctx.wallet_mut(), - Command::AMM(AmmProgramAgnosticSubcommand::SwapExactInput { - user_holding_a: public_mention(user_a), - user_holding_b: public_mention(user_b), - amount_in: 50, - min_amount_out: 1, - token_definition: def_a, - }), - ) + output + .step(ctx, "amm_swap_exact_input", async |ctx| { + wallet::cli::execute_subcommand( + ctx.wallet_mut(), + Command::AMM(AmmProgramAgnosticSubcommand::SwapExactInput { + user_holding_a: public_mention(user_a), + user_holding_b: public_mention(user_b), + amount_in: 50, + min_amount_out: 1, + token_definition: def_a, + }), + ) + .await + }) .await?; - let step = finalize_step("amm_swap_exact_input", started, pre_block, &ret, ctx).await?; - output.push(step); - } - { - let pre_block = crate::harness::begin_step(ctx).await?; - let started = Instant::now(); - let ret = wallet::cli::execute_subcommand( - ctx.wallet_mut(), - Command::AMM(AmmProgramAgnosticSubcommand::AddLiquidity { - user_holding_a: public_mention(user_a), - user_holding_b: public_mention(user_b), - user_holding_lp: public_mention(user_lp), - min_amount_lp: 1, - max_amount_a: 100, - max_amount_b: 100, - }), - ) + output + .step(ctx, "amm_add_liquidity", async |ctx| { + wallet::cli::execute_subcommand( + ctx.wallet_mut(), + Command::AMM(AmmProgramAgnosticSubcommand::AddLiquidity { + user_holding_a: public_mention(user_a), + user_holding_b: public_mention(user_b), + user_holding_lp: public_mention(user_lp), + min_amount_lp: 1, + max_amount_a: 100, + max_amount_b: 100, + }), + ) + .await + }) .await?; - let step = finalize_step("amm_add_liquidity", started, pre_block, &ret, ctx).await?; - output.push(step); - } - { - let pre_block = crate::harness::begin_step(ctx).await?; - let started = Instant::now(); - let ret = wallet::cli::execute_subcommand( - ctx.wallet_mut(), - Command::AMM(AmmProgramAgnosticSubcommand::RemoveLiquidity { - user_holding_a: public_mention(user_a), - user_holding_b: public_mention(user_b), - user_holding_lp: public_mention(user_lp), - balance_lp: 50, - min_amount_a: 1, - min_amount_b: 1, - }), - ) + output + .step(ctx, "amm_remove_liquidity", async |ctx| { + wallet::cli::execute_subcommand( + ctx.wallet_mut(), + Command::AMM(AmmProgramAgnosticSubcommand::RemoveLiquidity { + user_holding_a: public_mention(user_a), + user_holding_b: public_mention(user_b), + user_holding_lp: public_mention(user_lp), + balance_lp: 50, + min_amount_a: 1, + min_amount_b: 1, + }), + ) + .await + }) .await?; - let step = finalize_step("amm_remove_liquidity", started, pre_block, &ret, ctx).await?; - output.push(step); - } Ok(output) } async fn new_public_account( - ctx: &mut test_fixtures::TestContext, + ctx: &mut TestContext, output: &mut ScenarioOutput, label: &str, ) -> Result { - let pre_block = crate::harness::begin_step(ctx).await?; - let started = Instant::now(); - let ret = wallet::cli::execute_subcommand( - ctx.wallet_mut(), - Command::Account(AccountSubcommand::New(NewSubcommand::Public { - cci: None, - label: None, - })), - ) - .await?; - let step = finalize_step(label, started, pre_block, &ret, ctx).await?; - output.push(step); + let ret = output + .step(ctx, label, async |ctx| { + wallet::cli::execute_subcommand( + ctx.wallet_mut(), + Command::Account(AccountSubcommand::New(NewSubcommand::Public { + cci: None, + label: None, + })), + ) + .await + }) + .await?; match ret { SubcommandReturnValue::RegisterAccount { account_id } => Ok(account_id), other => bail!("expected RegisterAccount, got {other:?}"), @@ -148,53 +122,54 @@ async fn new_public_account( } async fn timed_token_new( - ctx: &mut test_fixtures::TestContext, + ctx: &mut TestContext, output: &mut ScenarioOutput, label: &str, def_id: nssa::AccountId, supply_id: nssa::AccountId, name: &str, ) -> Result<()> { - let pre_block = crate::harness::begin_step(ctx).await?; - let started = Instant::now(); - let ret = wallet::cli::execute_subcommand( - ctx.wallet_mut(), - Command::Token(TokenProgramAgnosticSubcommand::New { - definition_account_id: public_mention(def_id), - supply_account_id: public_mention(supply_id), - name: name.to_owned(), - total_supply: 10_000, - }), - ) - .await?; - let step = finalize_step(label, started, pre_block, &ret, ctx).await?; - output.push(step); + let name = name.to_owned(); + output + .step(ctx, label, async |ctx| { + wallet::cli::execute_subcommand( + ctx.wallet_mut(), + Command::Token(TokenProgramAgnosticSubcommand::New { + definition_account_id: public_mention(def_id), + supply_account_id: public_mention(supply_id), + name, + total_supply: 10_000, + }), + ) + .await + }) + .await?; Ok(()) } async fn timed_token_send( - ctx: &mut test_fixtures::TestContext, + ctx: &mut TestContext, output: &mut ScenarioOutput, label: &str, from_id: nssa::AccountId, to_id: nssa::AccountId, amount: u128, ) -> Result<()> { - let pre_block = crate::harness::begin_step(ctx).await?; - let started = Instant::now(); - let ret = wallet::cli::execute_subcommand( - ctx.wallet_mut(), - Command::Token(TokenProgramAgnosticSubcommand::Send { - from: public_mention(from_id), - to: Some(public_mention(to_id)), - to_npk: None, - to_vpk: None, - to_identifier: Some(0), - amount, - }), - ) - .await?; - let step = finalize_step(label, started, pre_block, &ret, ctx).await?; - output.push(step); + output + .step(ctx, label, async |ctx| { + wallet::cli::execute_subcommand( + ctx.wallet_mut(), + Command::Token(TokenProgramAgnosticSubcommand::Send { + from: public_mention(from_id), + to: Some(public_mention(to_id)), + to_npk: None, + to_vpk: None, + to_identifier: Some(0), + amount, + }), + ) + .await + }) + .await?; Ok(()) } diff --git a/tools/integration_bench/src/scenarios/fanout.rs b/tools/integration_bench/src/scenarios/fanout.rs index fc5235b5..d03adf83 100644 --- a/tools/integration_bench/src/scenarios/fanout.rs +++ b/tools/integration_bench/src/scenarios/fanout.rs @@ -1,42 +1,38 @@ //! Multi-recipient fanout: one funded supply pays 10 distinct recipients. -use std::time::Instant; - use anyhow::{Result, bail}; -use test_fixtures::public_mention; +use test_fixtures::{TestContext, public_mention}; use wallet::cli::{ Command, SubcommandReturnValue, account::{AccountSubcommand, NewSubcommand}, programs::token::TokenProgramAgnosticSubcommand, }; -use crate::harness::{ScenarioOutput, finalize_step}; +use crate::harness::ScenarioOutput; const FANOUT_COUNT: usize = 10; const AMOUNT_PER_TRANSFER: u128 = 100; -pub async fn run(ctx: &mut test_fixtures::TestContext) -> Result { +pub async fn run(ctx: &mut TestContext) -> Result { let mut output = ScenarioOutput::new("multi_recipient_fanout"); let def_id = new_public_account(ctx, &mut output, "create_acc_def").await?; let supply_id = new_public_account(ctx, &mut output, "create_acc_supply").await?; - { - let pre_block = crate::harness::begin_step(ctx).await?; - let started = Instant::now(); - let ret = wallet::cli::execute_subcommand( - ctx.wallet_mut(), - Command::Token(TokenProgramAgnosticSubcommand::New { - definition_account_id: public_mention(def_id), - supply_account_id: public_mention(supply_id), - name: "FanoutToken".to_owned(), - total_supply: 10_000_000, - }), - ) + output + .step(ctx, "token_new_fungible", async |ctx| { + wallet::cli::execute_subcommand( + ctx.wallet_mut(), + Command::Token(TokenProgramAgnosticSubcommand::New { + definition_account_id: public_mention(def_id), + supply_account_id: public_mention(supply_id), + name: "FanoutToken".to_owned(), + total_supply: 10_000_000, + }), + ) + .await + }) .await?; - let step = finalize_step("token_new_fungible", started, pre_block, &ret, ctx).await?; - output.push(step); - } let mut recipients = Vec::with_capacity(FANOUT_COUNT); for i in 0..FANOUT_COUNT { @@ -44,45 +40,45 @@ pub async fn run(ctx: &mut test_fixtures::TestContext) -> Result recipients.push(id); } - for (i, recipient_id) in recipients.iter().enumerate() { - let pre_block = crate::harness::begin_step(ctx).await?; - let started = Instant::now(); - let ret = wallet::cli::execute_subcommand( - ctx.wallet_mut(), - Command::Token(TokenProgramAgnosticSubcommand::Send { - from: public_mention(supply_id), - to: Some(public_mention(*recipient_id)), - to_npk: None, - to_vpk: None, - to_identifier: Some(0), - amount: AMOUNT_PER_TRANSFER, - }), - ) - .await?; - let step = finalize_step(format!("transfer_{i:02}"), started, pre_block, &ret, ctx).await?; - output.push(step); + for (i, recipient_id) in recipients.iter().copied().enumerate() { + output + .step(ctx, format!("transfer_{i:02}"), async |ctx| { + wallet::cli::execute_subcommand( + ctx.wallet_mut(), + Command::Token(TokenProgramAgnosticSubcommand::Send { + from: public_mention(supply_id), + to: Some(public_mention(recipient_id)), + to_npk: None, + to_vpk: None, + to_identifier: Some(0), + amount: AMOUNT_PER_TRANSFER, + }), + ) + .await + }) + .await?; } Ok(output) } async fn new_public_account( - ctx: &mut test_fixtures::TestContext, + ctx: &mut TestContext, output: &mut ScenarioOutput, label: &str, ) -> Result { - let pre_block = crate::harness::begin_step(ctx).await?; - let started = Instant::now(); - let ret = wallet::cli::execute_subcommand( - ctx.wallet_mut(), - Command::Account(AccountSubcommand::New(NewSubcommand::Public { - cci: None, - label: None, - })), - ) - .await?; - let step = finalize_step(label, started, pre_block, &ret, ctx).await?; - output.push(step); + let ret = output + .step(ctx, label, async |ctx| { + wallet::cli::execute_subcommand( + ctx.wallet_mut(), + Command::Account(AccountSubcommand::New(NewSubcommand::Public { + cci: None, + label: None, + })), + ) + .await + }) + .await?; match ret { SubcommandReturnValue::RegisterAccount { account_id } => Ok(account_id), other => bail!("expected RegisterAccount, got {other:?}"), diff --git a/tools/integration_bench/src/scenarios/parallel.rs b/tools/integration_bench/src/scenarios/parallel.rs index 7ae03a09..c6a265b9 100644 --- a/tools/integration_bench/src/scenarios/parallel.rs +++ b/tools/integration_bench/src/scenarios/parallel.rs @@ -15,7 +15,7 @@ use wallet::cli::{ programs::token::TokenProgramAgnosticSubcommand, }; -use crate::harness::{BlockSize, ScenarioOutput, StepResult, finalize_step}; +use crate::harness::{BlockSize, ScenarioOutput, StepResult}; const PARALLEL_FANOUT_N: usize = 10; const AMOUNT_PER_TRANSFER: u128 = 100; @@ -43,47 +43,47 @@ pub async fn run(ctx: &mut TestContext) -> Result { .expect("usize fits u128") .saturating_mul(AMOUNT_PER_TRANSFER) .saturating_mul(10); - { - let pre_block = crate::harness::begin_step(ctx).await?; - let started = Instant::now(); - let ret = wallet::cli::execute_subcommand( - ctx.wallet_mut(), - Command::Token(TokenProgramAgnosticSubcommand::New { - definition_account_id: public_mention(def_id), - supply_account_id: public_mention(master_id), - name: "ParToken".to_owned(), - total_supply: total_mint, - }), - ) + output + .step(ctx, "token_new_fungible", async |ctx| { + wallet::cli::execute_subcommand( + ctx.wallet_mut(), + Command::Token(TokenProgramAgnosticSubcommand::New { + definition_account_id: public_mention(def_id), + supply_account_id: public_mention(master_id), + name: "ParToken".to_owned(), + total_supply: total_mint, + }), + ) + .await + }) .await?; - let step = finalize_step("token_new_fungible", started, pre_block, &ret, ctx).await?; - output.push(step); - } // Fund each sender from master. Serial; this is setup, not measured throughput. - for (i, sender_id) in senders.iter().enumerate() { - let pre_block = crate::harness::begin_step(ctx).await?; - let started = Instant::now(); - let ret = wallet::cli::execute_subcommand( - ctx.wallet_mut(), - Command::Token(TokenProgramAgnosticSubcommand::Send { - from: public_mention(master_id), - to: Some(public_mention(*sender_id)), - to_npk: None, - to_vpk: None, - to_identifier: Some(0), - amount: AMOUNT_PER_TRANSFER * 5, - }), - ) - .await?; - let step = - finalize_step(format!("fund_sender_{i:02}"), started, pre_block, &ret, ctx).await?; - output.push(step); + for (i, sender_id) in senders.iter().copied().enumerate() { + output + .step(ctx, format!("fund_sender_{i:02}"), async |ctx| { + wallet::cli::execute_subcommand( + ctx.wallet_mut(), + Command::Token(TokenProgramAgnosticSubcommand::Send { + from: public_mention(master_id), + to: Some(public_mention(sender_id)), + to_npk: None, + to_vpk: None, + to_identifier: Some(0), + amount: AMOUNT_PER_TRANSFER * 5, + }), + ) + .await + }) + .await?; } // The measured phase: submit N transfers as fast as possible, do not wait // for chain advance between submits. The sequencer batches whatever lands in - // its mempool before block_create_timeout. + // its mempool before block_create_timeout. The burst step is captured + // manually rather than via the `step()` helper because we need to time + // submit-and-inclusion as two separate intervals over a synthesised batch + // rather than per-tx. let pre_block_burst = ctx.sequencer_client().get_last_block_id().await?; let burst_started = Instant::now(); @@ -169,18 +169,18 @@ async fn new_public_account( output: &mut ScenarioOutput, label: &str, ) -> Result { - let pre_block = crate::harness::begin_step(ctx).await?; - let started = Instant::now(); - let ret = wallet::cli::execute_subcommand( - ctx.wallet_mut(), - Command::Account(AccountSubcommand::New(NewSubcommand::Public { - cci: None, - label: None, - })), - ) - .await?; - let step = finalize_step(label, started, pre_block, &ret, ctx).await?; - output.push(step); + let ret = output + .step(ctx, label, async |ctx| { + wallet::cli::execute_subcommand( + ctx.wallet_mut(), + Command::Account(AccountSubcommand::New(NewSubcommand::Public { + cci: None, + label: None, + })), + ) + .await + }) + .await?; match ret { SubcommandReturnValue::RegisterAccount { account_id } => Ok(account_id), other => bail!("expected RegisterAccount, got {other:?}"), diff --git a/tools/integration_bench/src/scenarios/private.rs b/tools/integration_bench/src/scenarios/private.rs index 54dcab2b..2be8c43c 100644 --- a/tools/integration_bench/src/scenarios/private.rs +++ b/tools/integration_bench/src/scenarios/private.rs @@ -1,18 +1,16 @@ //! Private chained flow: shielded, deshielded, and private-to-private transfers. -use std::time::Instant; - use anyhow::{Result, bail}; -use test_fixtures::{private_mention, public_mention}; +use test_fixtures::{TestContext, private_mention, public_mention}; use wallet::cli::{ Command, SubcommandReturnValue, account::{AccountSubcommand, NewSubcommand}, programs::token::TokenProgramAgnosticSubcommand, }; -use crate::harness::{ScenarioOutput, finalize_step}; +use crate::harness::ScenarioOutput; -pub async fn run(ctx: &mut test_fixtures::TestContext) -> Result { +pub async fn run(ctx: &mut TestContext) -> Result { let mut output = ScenarioOutput::new("private_chained_flow"); let def_id = new_public_account(ctx, &mut output, "create_acc_def").await?; @@ -23,103 +21,95 @@ pub async fn run(ctx: &mut test_fixtures::TestContext) -> Result let private_b = new_private_account(ctx, &mut output, "create_acc_priv_b").await?; // Mint into public supply. - { - let pre_block = crate::harness::begin_step(ctx).await?; - let started = Instant::now(); - let ret = wallet::cli::execute_subcommand( - ctx.wallet_mut(), - Command::Token(TokenProgramAgnosticSubcommand::New { - definition_account_id: public_mention(def_id), - supply_account_id: public_mention(supply_id), - name: "PrivToken".to_owned(), - total_supply: 1_000_000, - }), - ) + output + .step(ctx, "token_new_fungible", async |ctx| { + wallet::cli::execute_subcommand( + ctx.wallet_mut(), + Command::Token(TokenProgramAgnosticSubcommand::New { + definition_account_id: public_mention(def_id), + supply_account_id: public_mention(supply_id), + name: "PrivToken".to_owned(), + total_supply: 1_000_000, + }), + ) + .await + }) .await?; - let step = finalize_step("token_new_fungible", started, pre_block, &ret, ctx).await?; - output.push(step); - } // Shielded transfer: public supply -> private_a. - { - let pre_block = crate::harness::begin_step(ctx).await?; - let started = Instant::now(); - let ret = wallet::cli::execute_subcommand( - ctx.wallet_mut(), - Command::Token(TokenProgramAgnosticSubcommand::Send { - from: public_mention(supply_id), - to: Some(private_mention(private_a)), - to_npk: None, - to_vpk: None, - to_identifier: Some(0), - amount: 1_000, - }), - ) + output + .step(ctx, "shielded_transfer", async |ctx| { + wallet::cli::execute_subcommand( + ctx.wallet_mut(), + Command::Token(TokenProgramAgnosticSubcommand::Send { + from: public_mention(supply_id), + to: Some(private_mention(private_a)), + to_npk: None, + to_vpk: None, + to_identifier: Some(0), + amount: 1_000, + }), + ) + .await + }) .await?; - let step = finalize_step("shielded_transfer", started, pre_block, &ret, ctx).await?; - output.push(step); - } // Deshielded transfer: private_a -> public_recipient. - { - let pre_block = crate::harness::begin_step(ctx).await?; - let started = Instant::now(); - let ret = wallet::cli::execute_subcommand( - ctx.wallet_mut(), - Command::Token(TokenProgramAgnosticSubcommand::Send { - from: private_mention(private_a), - to: Some(public_mention(public_recipient_id)), - to_npk: None, - to_vpk: None, - to_identifier: Some(0), - amount: 100, - }), - ) + output + .step(ctx, "deshielded_transfer", async |ctx| { + wallet::cli::execute_subcommand( + ctx.wallet_mut(), + Command::Token(TokenProgramAgnosticSubcommand::Send { + from: private_mention(private_a), + to: Some(public_mention(public_recipient_id)), + to_npk: None, + to_vpk: None, + to_identifier: Some(0), + amount: 100, + }), + ) + .await + }) .await?; - let step = finalize_step("deshielded_transfer", started, pre_block, &ret, ctx).await?; - output.push(step); - } // Private-to-private transfer: private_a -> private_b. - { - let pre_block = crate::harness::begin_step(ctx).await?; - let started = Instant::now(); - let ret = wallet::cli::execute_subcommand( - ctx.wallet_mut(), - Command::Token(TokenProgramAgnosticSubcommand::Send { - from: private_mention(private_a), - to: Some(private_mention(private_b)), - to_npk: None, - to_vpk: None, - to_identifier: Some(0), - amount: 200, - }), - ) + output + .step(ctx, "private_to_private", async |ctx| { + wallet::cli::execute_subcommand( + ctx.wallet_mut(), + Command::Token(TokenProgramAgnosticSubcommand::Send { + from: private_mention(private_a), + to: Some(private_mention(private_b)), + to_npk: None, + to_vpk: None, + to_identifier: Some(0), + amount: 200, + }), + ) + .await + }) .await?; - let step = finalize_step("private_to_private", started, pre_block, &ret, ctx).await?; - output.push(step); - } Ok(output) } async fn new_public_account( - ctx: &mut test_fixtures::TestContext, + ctx: &mut TestContext, output: &mut ScenarioOutput, label: &str, ) -> Result { - let pre_block = crate::harness::begin_step(ctx).await?; - let started = Instant::now(); - let ret = wallet::cli::execute_subcommand( - ctx.wallet_mut(), - Command::Account(AccountSubcommand::New(NewSubcommand::Public { - cci: None, - label: None, - })), - ) - .await?; - let step = finalize_step(label, started, pre_block, &ret, ctx).await?; - output.push(step); + let ret = output + .step(ctx, label, async |ctx| { + wallet::cli::execute_subcommand( + ctx.wallet_mut(), + Command::Account(AccountSubcommand::New(NewSubcommand::Public { + cci: None, + label: None, + })), + ) + .await + }) + .await?; match ret { SubcommandReturnValue::RegisterAccount { account_id } => Ok(account_id), other => bail!("expected RegisterAccount, got {other:?}"), @@ -127,22 +117,22 @@ async fn new_public_account( } async fn new_private_account( - ctx: &mut test_fixtures::TestContext, + ctx: &mut TestContext, output: &mut ScenarioOutput, label: &str, ) -> Result { - let pre_block = crate::harness::begin_step(ctx).await?; - let started = Instant::now(); - let ret = wallet::cli::execute_subcommand( - ctx.wallet_mut(), - Command::Account(AccountSubcommand::New(NewSubcommand::Private { - cci: None, - label: None, - })), - ) - .await?; - let step = finalize_step(label, started, pre_block, &ret, ctx).await?; - output.push(step); + let ret = output + .step(ctx, label, async |ctx| { + wallet::cli::execute_subcommand( + ctx.wallet_mut(), + Command::Account(AccountSubcommand::New(NewSubcommand::Private { + cci: None, + label: None, + })), + ) + .await + }) + .await?; match ret { SubcommandReturnValue::RegisterAccount { account_id } => Ok(account_id), other => bail!("expected RegisterAccount, got {other:?}"), diff --git a/tools/integration_bench/src/scenarios/token.rs b/tools/integration_bench/src/scenarios/token.rs index 235394e0..d1dfdef3 100644 --- a/tools/integration_bench/src/scenarios/token.rs +++ b/tools/integration_bench/src/scenarios/token.rs @@ -1,102 +1,94 @@ //! Token onboarding scenario: create accounts, mint, public transfer, private transfer. -use std::time::Instant; - use anyhow::{Result, bail}; -use test_fixtures::{private_mention, public_mention}; +use test_fixtures::{TestContext, private_mention, public_mention}; use wallet::cli::{ Command, SubcommandReturnValue, account::{AccountSubcommand, NewSubcommand}, programs::token::TokenProgramAgnosticSubcommand, }; -use crate::harness::{ScenarioOutput, finalize_step}; +use crate::harness::ScenarioOutput; -pub async fn run(ctx: &mut test_fixtures::TestContext) -> Result { +pub async fn run(ctx: &mut TestContext) -> Result { let mut output = ScenarioOutput::new("token_onboarding"); let definition_id = new_public_account(ctx, &mut output, "create_pub_definition").await?; let supply_id = new_public_account(ctx, &mut output, "create_pub_supply").await?; let recipient_id = new_public_account(ctx, &mut output, "create_pub_recipient").await?; - { - let pre_block = crate::harness::begin_step(ctx).await?; - let started = Instant::now(); - let ret = wallet::cli::execute_subcommand( - ctx.wallet_mut(), - Command::Token(TokenProgramAgnosticSubcommand::New { - definition_account_id: public_mention(definition_id), - supply_account_id: public_mention(supply_id), - name: "BenchToken".to_owned(), - total_supply: 1_000_000, - }), - ) + output + .step(ctx, "token_new_fungible", async |ctx| { + wallet::cli::execute_subcommand( + ctx.wallet_mut(), + Command::Token(TokenProgramAgnosticSubcommand::New { + definition_account_id: public_mention(definition_id), + supply_account_id: public_mention(supply_id), + name: "BenchToken".to_owned(), + total_supply: 1_000_000, + }), + ) + .await + }) .await?; - let step = finalize_step("token_new_fungible", started, pre_block, &ret, ctx).await?; - output.push(step); - } - { - let pre_block = crate::harness::begin_step(ctx).await?; - let started = Instant::now(); - let ret = wallet::cli::execute_subcommand( - ctx.wallet_mut(), - Command::Token(TokenProgramAgnosticSubcommand::Send { - from: public_mention(supply_id), - to: Some(public_mention(recipient_id)), - to_npk: None, - to_vpk: None, - to_identifier: Some(0), - amount: 1_000, - }), - ) + output + .step(ctx, "token_public_transfer", async |ctx| { + wallet::cli::execute_subcommand( + ctx.wallet_mut(), + Command::Token(TokenProgramAgnosticSubcommand::Send { + from: public_mention(supply_id), + to: Some(public_mention(recipient_id)), + to_npk: None, + to_vpk: None, + to_identifier: Some(0), + amount: 1_000, + }), + ) + .await + }) .await?; - let step = finalize_step("token_public_transfer", started, pre_block, &ret, ctx).await?; - output.push(step); - } let private_recipient_id = new_private_account(ctx, &mut output, "create_priv_recipient").await?; - { - let pre_block = crate::harness::begin_step(ctx).await?; - let started = Instant::now(); - let ret = wallet::cli::execute_subcommand( - ctx.wallet_mut(), - Command::Token(TokenProgramAgnosticSubcommand::Send { - from: public_mention(supply_id), - to: Some(private_mention(private_recipient_id)), - to_npk: None, - to_vpk: None, - to_identifier: Some(0), - amount: 500, - }), - ) + output + .step(ctx, "token_shielded_transfer", async |ctx| { + wallet::cli::execute_subcommand( + ctx.wallet_mut(), + Command::Token(TokenProgramAgnosticSubcommand::Send { + from: public_mention(supply_id), + to: Some(private_mention(private_recipient_id)), + to_npk: None, + to_vpk: None, + to_identifier: Some(0), + amount: 500, + }), + ) + .await + }) .await?; - let step = finalize_step("token_shielded_transfer", started, pre_block, &ret, ctx).await?; - output.push(step); - } Ok(output) } async fn new_public_account( - ctx: &mut test_fixtures::TestContext, + ctx: &mut TestContext, output: &mut ScenarioOutput, label: &str, ) -> Result { - let pre_block = crate::harness::begin_step(ctx).await?; - let started = Instant::now(); - let ret = wallet::cli::execute_subcommand( - ctx.wallet_mut(), - Command::Account(AccountSubcommand::New(NewSubcommand::Public { - cci: None, - label: None, - })), - ) - .await?; - let step = finalize_step(label, started, pre_block, &ret, ctx).await?; - output.push(step); + let ret = output + .step(ctx, label, async |ctx| { + wallet::cli::execute_subcommand( + ctx.wallet_mut(), + Command::Account(AccountSubcommand::New(NewSubcommand::Public { + cci: None, + label: None, + })), + ) + .await + }) + .await?; match ret { SubcommandReturnValue::RegisterAccount { account_id } => Ok(account_id), other => bail!("expected RegisterAccount, got {other:?}"), @@ -104,22 +96,22 @@ async fn new_public_account( } async fn new_private_account( - ctx: &mut test_fixtures::TestContext, + ctx: &mut TestContext, output: &mut ScenarioOutput, label: &str, ) -> Result { - let pre_block = crate::harness::begin_step(ctx).await?; - let started = Instant::now(); - let ret = wallet::cli::execute_subcommand( - ctx.wallet_mut(), - Command::Account(AccountSubcommand::New(NewSubcommand::Private { - cci: None, - label: None, - })), - ) - .await?; - let step = finalize_step(label, started, pre_block, &ret, ctx).await?; - output.push(step); + let ret = output + .step(ctx, label, async |ctx| { + wallet::cli::execute_subcommand( + ctx.wallet_mut(), + Command::Account(AccountSubcommand::New(NewSubcommand::Private { + cci: None, + label: None, + })), + ) + .await + }) + .await?; match ret { SubcommandReturnValue::RegisterAccount { account_id } => Ok(account_id), other => bail!("expected RegisterAccount, got {other:?}"),