Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add benchmark for simple transaction #577

Merged
merged 28 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
0667acd
feat: add benchmark for default transaction
Fumuran Apr 8, 2024
b63fbf7
refactor: use trace instead of emit, create wrapper for host
Fumuran Apr 10, 2024
d3943e9
refactor: improve cycles print
Fumuran Apr 10, 2024
c823d82
refactor: add inline comments, change trace ids
Fumuran Apr 10, 2024
7e79a5b
chore: ignore the test untill it become a binary
Fumuran Apr 10, 2024
74e99fd
refactor: organise cycles storing, add traces for each note
Fumuran Apr 11, 2024
b7c22b1
feat: create a simple cli for benchmark binary package
Fumuran Apr 11, 2024
4e33ee8
feat: create cargo-make script for benchmarking, move benchmarks back…
Fumuran Apr 12, 2024
cdf40f9
Merge branch 'next' into andrew-tx-execution-bench
Fumuran Apr 12, 2024
b919a14
refactor: move TransactionProgress to the TransactionHost
Fumuran Apr 12, 2024
dd97cb5
feat: implement bench for P2ID note, add NoteId to the output
Fumuran Apr 13, 2024
ff5d2fd
refactor: move last note id obtaining to the separate function
Fumuran Apr 15, 2024
e3bb648
refactor: fix no-std build
Fumuran Apr 15, 2024
0323b67
refactor: update comments in main.masm file to be consistent with api…
Fumuran Apr 17, 2024
118f371
feat: write benchmark results to the json file
Fumuran Apr 18, 2024
f7d446b
Merge branch 'next' into andrew-tx-execution-bench
Fumuran Apr 18, 2024
58e0324
refactor: move benchmarks to their own crate
Fumuran Apr 18, 2024
ea8e5ba
refactor: add ability to run all benches
Fumuran Apr 18, 2024
d2bfbf3
refactor: update bin name, dependencies; remove benches except all
Fumuran Apr 22, 2024
d6a0d9b
Merge branch 'next' into andrew-tx-execution-bench
Fumuran Apr 22, 2024
b9d6473
chore: fix no-std build
Fumuran Apr 22, 2024
1fe5ad2
refactor: rework TransactionProgress serialization
Fumuran Apr 24, 2024
4e284aa
refactor: exclude bench-tx from no-std build, update dependencies
Fumuran Apr 24, 2024
a06ca80
refactor: improve imports formatting
Fumuran Apr 24, 2024
fad7743
refactor: rework writing to json
Fumuran Apr 25, 2024
fc99ee2
chore: change visibility of miden-tx MockDataStore
Fumuran Apr 25, 2024
52d614b
Merge branch 'next' into andrew-tx-execution-bench
Fumuran Apr 25, 2024
4016957
chore: update CHANGELOG, create README for bench-tx
Fumuran Apr 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[workspace]
resolver = "2"
members = [
members = [
"bench-tx",
"miden-lib",
"miden-tx",
"mock",
Expand Down
11 changes: 9 additions & 2 deletions Makefile.toml
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,16 @@ args = ["build", "--release"]
[tasks.build-no-std]
description = "Build using no-std"
command = "cargo"
args = ["build", "--no-default-features", "--target", "wasm32-unknown-unknown", "--workspace", "--exclude", "miden-mock"]
args = ["build", "--no-default-features", "--target", "wasm32-unknown-unknown", "--workspace", "--exclude", "miden-mock", "--exclude", "miden-bench-tx"]
bobbinth marked this conversation as resolved.
Show resolved Hide resolved

# --- utilities ----------------------------------------------------------------------------------------
# --- benchmarking --------------------------------------------------------------------------------
[tasks.bench-tx]
description = "Run all available transaction benchmarks"
workspace = false
command = "cargo"
args = ["run", "--bin", "bench-tx"]

# --- utilities -----------------------------------------------------------------------------------
[tasks.watch]
description = "Watch for changes and rebuild"
workspace = false
Expand Down
23 changes: 23 additions & 0 deletions bench-tx/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[package]
name = "miden-bench-tx"
version = "0.1.0"
edition.workspace = true
rust-version.workspace = true
license.workspace = true
authors.workspace = true
homepage.workspace = true
repository.workspace = true
exclude.workspace = true

[[bin]]
name = "bench-tx"
path = "src/main.rs"

[dependencies]
miden-lib = { package = "miden-lib", path = "../miden-lib", version = "0.3" }
miden-objects = { package = "miden-objects", path = "../objects", version = "0.3" }
miden-tx = { package = "miden-tx", path = "../miden-tx", version = "0.3" }
mock = { package = "miden-mock", path = "../mock" }
serde = { package = "serde", version = "1.0" }
serde_json = { package = "serde_json", version = "1.0", features = ["preserve_order"] }
vm-processor = { workspace = true }
21 changes: 21 additions & 0 deletions bench-tx/bench-tx.json
bobbinth marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"simple": {
"prologue": 3644,
"notes_processing": 1151,
"note_execution": {
"0x47b2fbff8a3f09e40343238e7b15c8918d7c63e570fd1b3c904ada458c4d74bd": 392,
"0x8a55c3531cdd5725aa805475093ed3006c6773b71a008e8ca840da8364a67cd6": 715
},
"tx_script_processing": 32,
"epilogue": 2222
},
"p2id": {
"prologue": 2004,
"notes_processing": 920,
"note_execution": {
"0xb9fa30eb43d80d579be02dc004338e06b5ad565e81e0bac11a94ab01abfdd40a": 883
},
"tx_script_processing": 88209,
"epilogue": 272
}
}
163 changes: 163 additions & 0 deletions bench-tx/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
use core::fmt;
use std::{
fs::{read_to_string, write, File},
io::Write,
path::Path,
};

use miden_lib::{
notes::create_p2id_note, transaction::ToTransactionKernelInputs, utils::Serializable,
};
use miden_objects::{
accounts::AccountId,
assembly::ProgramAst,
assets::{Asset, FungibleAsset},
crypto::{dsa::rpo_falcon512::SecretKey, rand::RpoRandomCoin},
notes::NoteType,
transaction::TransactionArgs,
Felt,
};
use miden_tx::{TransactionExecutor, TransactionHost, TransactionProgress};
use vm_processor::{ExecutionOptions, RecAdviceProvider, Word};

mod utils;
use utils::{
get_account_with_default_account_code, write_bench_results_to_json, MockDataStore, String,
ToString, Vec, ACCOUNT_ID_FUNGIBLE_FAUCET_ON_CHAIN,
ACCOUNT_ID_REGULAR_ACCOUNT_UPDATABLE_CODE_OFF_CHAIN, ACCOUNT_ID_SENDER, DEFAULT_AUTH_SCRIPT,
};

pub enum Benchmark {
Simple,
P2ID,
}

impl fmt::Display for Benchmark {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Benchmark::Simple => write!(f, "simple"),
Benchmark::P2ID => write!(f, "p2id"),
}
}
}

fn main() -> Result<(), String> {
// create a template file for benchmark results
let path = Path::new("bench-tx/bench-tx.json");
let mut file = File::create(path).map_err(|e| e.to_string())?;
file.write_all(b"{}").map_err(|e| e.to_string())?;

// run all available benchmarks
let benchmark_results = vec![
(Benchmark::Simple, benchmark_default_tx()?),
(Benchmark::P2ID, benchmark_p2id()?),
];

// store benchmark results in the JSON file
write_bench_results_to_json(path, benchmark_results)?;

Ok(())
}

// BENCHMARKS
// ================================================================================================

/// Runs the default transaction with empty transaction script and two default notes.
pub fn benchmark_default_tx() -> Result<TransactionProgress, String> {
let data_store = MockDataStore::default();
let mut executor = TransactionExecutor::new(data_store.clone()).with_tracing();

let account_id = data_store.account.id();
executor.load_account(account_id).map_err(|e| e.to_string())?;

let block_ref = data_store.block_header.block_num();
let note_ids = data_store.notes.iter().map(|note| note.id()).collect::<Vec<_>>();

let transaction = executor
.prepare_transaction(account_id, block_ref, &note_ids, data_store.tx_args().clone())
.map_err(|e| e.to_string())?;

let (stack_inputs, advice_inputs) = transaction.get_kernel_inputs();
let advice_recorder: RecAdviceProvider = advice_inputs.into();
let mut host = TransactionHost::new(transaction.account().into(), advice_recorder);

vm_processor::execute(
transaction.program(),
stack_inputs,
&mut host,
ExecutionOptions::default().with_tracing(),
)
.map_err(|e| e.to_string())?;

Ok(host.tx_progress().clone())
}

/// Runs the transaction which consumes a P2ID note into a basic wallet.
pub fn benchmark_p2id() -> Result<TransactionProgress, String> {
// Create assets
let faucet_id = AccountId::try_from(ACCOUNT_ID_FUNGIBLE_FAUCET_ON_CHAIN).unwrap();
let fungible_asset: Asset = FungibleAsset::new(faucet_id, 100).unwrap().into();

// Create sender and target account
let sender_account_id = AccountId::try_from(ACCOUNT_ID_SENDER).unwrap();

let target_account_id =
AccountId::try_from(ACCOUNT_ID_REGULAR_ACCOUNT_UPDATABLE_CODE_OFF_CHAIN).unwrap();
let sec_key = SecretKey::new();
let target_pub_key: Word = sec_key.public_key().into();
let mut pk_sk_bytes = sec_key.to_bytes();
pk_sk_bytes.append(&mut target_pub_key.to_bytes());
let target_sk_pk_felt: Vec<Felt> =
pk_sk_bytes.iter().map(|a| Felt::new(*a as u64)).collect::<Vec<Felt>>();
let target_account =
get_account_with_default_account_code(target_account_id, target_pub_key, None);

// Create the note
let note = create_p2id_note(
sender_account_id,
target_account_id,
vec![fungible_asset],
NoteType::Public,
RpoRandomCoin::new([Felt::new(1), Felt::new(2), Felt::new(3), Felt::new(4)]),
)
.unwrap();

let data_store =
MockDataStore::with_existing(Some(target_account.clone()), Some(vec![note.clone()]));

let mut executor = TransactionExecutor::new(data_store.clone()).with_tracing();
executor.load_account(target_account_id).unwrap();

let block_ref = data_store.block_header.block_num();
let note_ids = data_store.notes.iter().map(|note| note.id()).collect::<Vec<_>>();

let tx_script_code = ProgramAst::parse(DEFAULT_AUTH_SCRIPT).unwrap();

let tx_script_target = executor
.compile_tx_script(
tx_script_code.clone(),
vec![(target_pub_key, target_sk_pk_felt)],
vec![],
)
.unwrap();
let tx_args_target = TransactionArgs::with_tx_script(tx_script_target);

// execute transaction
let transaction = executor
.prepare_transaction(target_account_id, block_ref, &note_ids, tx_args_target)
.map_err(|e| e.to_string())?;

let (stack_inputs, advice_inputs) = transaction.get_kernel_inputs();
let advice_recorder: RecAdviceProvider = advice_inputs.into();
let mut host = TransactionHost::new(transaction.account().into(), advice_recorder);

vm_processor::execute(
transaction.program(),
stack_inputs,
&mut host,
ExecutionOptions::default().with_tracing(),
)
.map_err(|e| e.to_string())?;

Ok(host.tx_progress().clone())
}
Loading
Loading