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 9 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
1 change: 1 addition & 0 deletions Cargo.lock

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

9 changes: 8 additions & 1 deletion Makefile.toml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,14 @@ description = "Build using no-std"
command = "cargo"
args = ["build", "--no-default-features", "--target", "wasm32-unknown-unknown", "--workspace", "--exclude", "miden-mock"]

# --- utilities ----------------------------------------------------------------------------------------
# --- benchmarking --------------------------------------------------------------------------------
[tasks.bench-simple]
bobbinth marked this conversation as resolved.
Show resolved Hide resolved
description = "Run transaction benchmark with default transaction script and notes"
workspace = false
command = "cargo"
args = ["run", "--bin", "benchmarks", "--features", "executable", "simple"]

# --- utilities -----------------------------------------------------------------------------------
[tasks.watch]
description = "Watch for changes and rebuild"
workspace = false
Expand Down
78 changes: 78 additions & 0 deletions miden-lib/asm/kernels/transaction/main.masm
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,40 @@ use.miden::kernels::tx::memory
use.miden::kernels::tx::note
use.miden::kernels::tx::prologue

# TRACES
# =================================================================================================

# Trace emitted to signal that an execution of the transaction prologue has started.
const.PROLOGUE_START=131072
# Trace emitted to signal that an execution of the transaction prologue has ended.
const.PROLOGUE_END=131073

# Trace emitted to signal that the notes processing has started.
const.NOTES_PROCESSING_START=131074
# Trace emitted to signal that the notes processing has ended.
const.NOTES_PROCESSING_END=131075

# Trace emitted to signal that the note consuming has started.
const.NOTE_CONSUMING_START=131076
# Trace emitted to signal that the note consuming has ended.
const.NOTE_CONSUMING_END=131077
bobbinth marked this conversation as resolved.
Show resolved Hide resolved

# Trace emitted to signal that the transaction script processing has started.
const.TX_SCRIPT_PROCESSING_START=131078
# Trace emitted to signal that the transaction script processing has ended.
const.TX_SCRIPT_PROCESSING_END=131079

# Trace emitted to signal that an execution of the transaction epilogue has started.
const.EPILOGUE_START=131080
# Trace emitted to signal that an execution of the transaction epilogue has ended.
const.EPILOGUE_END=131081

# Trace emmited to signal that an execution of the program has ended.
const.EXECUTION_END=196607

# MAIN
# =================================================================================================

#! This is the entrypoint for the transaction kernel program. It is composed of the following
#! program sections:
#!
Expand Down Expand Up @@ -64,13 +98,25 @@ proc.main.1
# Prologue
# ---------------------------------------------------------------------------------------------

# add redundant instructions to make span non-empty
push.0 drop
trace.PROLOGUE_START

# execute the transaction prologue
exec.prologue::prepare_transaction
# => []

# add redundant instructions to make span non-empty
push.0 drop
bobbinth marked this conversation as resolved.
Show resolved Hide resolved
trace.PROLOGUE_END

# Note Processing
# ---------------------------------------------------------------------------------------------

# add redundant instructions to make span non-empty
push.0 drop
trace.NOTES_PROCESSING_START

# get the total number of consumed notes
exec.memory::get_total_num_consumed_notes
# => [num_consumed_notes]
Expand All @@ -86,6 +132,10 @@ proc.main.1

# loop while we have notes to consume
while.true
# add redundant instructions to make span non-empty
push.0 drop
trace.NOTE_CONSUMING_START

# execute the note setup script
exec.note::prepare_note
# => [NOTE_SCRIPT_HASH, NOTE_ARGS]
Expand All @@ -103,15 +153,27 @@ proc.main.1
loc_load.0
neq
# => [should_loop]

# add redundant instructions to make span non-empty
push.0 drop
trace.NOTE_CONSUMING_END
end

# execute note processing teardown
exec.note::note_processing_teardown
# => []

# add redundant instructions to make span non-empty
push.0 drop
trace.NOTES_PROCESSING_END

# Transaction Script Processing
# ---------------------------------------------------------------------------------------------

# add redundant instructions to make span non-empty
push.0 drop
trace.TX_SCRIPT_PROCESSING_START

# execute the transaction script
exec.memory::get_tx_script_root
# => [TX_SCRIPT_ROOT]
Expand All @@ -133,14 +195,30 @@ proc.main.1
# => []
end

# add redundant instructions to make span non-empty
push.0 drop
trace.TX_SCRIPT_PROCESSING_END

# Epilogue
# ---------------------------------------------------------------------------------------------

# add redundant instructions to make span non-empty
push.0 drop
trace.EPILOGUE_START

# execute the transaction epilogue
exec.epilogue::finalize_transaction
# => [TX_SCRIPT_ROOT, CREATED_NOTES_COMMITMENT, FINAL_ACCOUNT_HASH]

# add redundant instructions to make span non-empty
push.0 drop
trace.EPILOGUE_END
end

begin
exec.main

# add redundant instructions to make span non-empty
push.0 drop
trace.EXECUTION_END
end
25 changes: 25 additions & 0 deletions miden-lib/src/transaction/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,28 @@ impl fmt::Display for TransactionEventParsingError {

#[cfg(feature = "std")]
impl std::error::Error for TransactionEventParsingError {}

// TRANSACTION TRACE PARSING ERROR
// ================================================================================================

#[derive(Debug, Clone, Eq, PartialEq)]
pub enum TransactionTraceParsingError {
InvalidTransactionTrace(u32),
NotTransactionTrace(u32),
}

impl fmt::Display for TransactionTraceParsingError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::InvalidTransactionTrace(trace_id) => {
write!(f, "trace {trace_id} is invalid")
},
Self::NotTransactionTrace(trace_id) => {
write!(f, "trace {trace_id} is not a transaction kernel trace")
},
}
}
}

#[cfg(feature = "std")]
impl std::error::Error for TransactionTraceParsingError {}
66 changes: 59 additions & 7 deletions miden-lib/src/transaction/events.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
use core::fmt;

use super::TransactionEventParsingError;
use super::{TransactionEventParsingError, TransactionTraceParsingError};

// CONSTANTS
// ================================================================================================

/// Value of the top 16 bits of a transaction kernel event ID.
pub const EVENT_ID_PREFIX: u32 = 2;

// TRANSACTION EVENT
// ================================================================================================
Expand Down Expand Up @@ -30,11 +36,6 @@ pub enum TransactionEvent {
NoteCreated = NOTE_CREATED,
}

impl TransactionEvent {
/// Value of the top 16 bits of a transaction kernel event ID.
pub const EVENT_ID_PREFIX: u16 = 2;
}

impl fmt::Display for TransactionEvent {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{self:?}")
Expand All @@ -45,7 +46,7 @@ impl TryFrom<u32> for TransactionEvent {
type Error = TransactionEventParsingError;

fn try_from(value: u32) -> Result<Self, Self::Error> {
if value >> 16 != Self::EVENT_ID_PREFIX as u32 {
if value >> 16 != EVENT_ID_PREFIX {
return Err(TransactionEventParsingError::NotTransactionEvent(value));
}

Expand All @@ -60,3 +61,54 @@ impl TryFrom<u32> for TransactionEvent {
}
}
}

// TRANSACTION TRACE
// ================================================================================================

#[repr(u32)]
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum TransactionTrace {
PrologueStart = 0x2_0000, // 131072
PrologueEnd = 0x2_0001, // 131073
NotesProcessingStart = 0x2_0002, // 131074
NotesProcessingEnd = 0x2_0003, // 131075
NoteConsumingStart = 0x2_0004, // 131076
NoteConsumingEnd = 0x2_0005, // 131077
TxScriptProcessingStart = 0x2_0006, // 131078
TxScriptProcessingEnd = 0x2_0007, // 131079
EpilogueStart = 0x2_0008, // 131080
EpilogueEnd = 0x2_0009, // 131081

ExecutionEnd = 0x2_FFFF, // 196607
}

impl fmt::Display for TransactionTrace {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{self:?}")
}
}

impl TryFrom<u32> for TransactionTrace {
type Error = TransactionTraceParsingError;

fn try_from(value: u32) -> Result<Self, Self::Error> {
if value >> 16 != EVENT_ID_PREFIX {
return Err(TransactionTraceParsingError::NotTransactionTrace(value));
}

match value {
0x2_0000 => Ok(TransactionTrace::PrologueStart),
0x2_0001 => Ok(TransactionTrace::PrologueEnd),
0x2_0002 => Ok(TransactionTrace::NotesProcessingStart),
0x2_0003 => Ok(TransactionTrace::NotesProcessingEnd),
0x2_0004 => Ok(TransactionTrace::NoteConsumingStart),
0x2_0005 => Ok(TransactionTrace::NoteConsumingEnd),
0x2_0006 => Ok(TransactionTrace::TxScriptProcessingStart),
0x2_0007 => Ok(TransactionTrace::TxScriptProcessingEnd),
0x2_0008 => Ok(TransactionTrace::EpilogueStart),
0x2_0009 => Ok(TransactionTrace::EpilogueEnd),
0x2_FFFF => Ok(TransactionTrace::ExecutionEnd),
_ => Err(TransactionTraceParsingError::InvalidTransactionTrace(value)),
}
}
}
6 changes: 4 additions & 2 deletions miden-lib/src/transaction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use super::MidenLib;
pub mod memory;

mod events;
pub use events::TransactionEvent;
pub use events::{TransactionEvent, TransactionTrace};

mod inputs;
pub use inputs::ToTransactionKernelInputs;
Expand All @@ -27,7 +27,9 @@ pub use outputs::{
};

mod errors;
pub use errors::{TransactionEventParsingError, TransactionKernelError};
pub use errors::{
TransactionEventParsingError, TransactionKernelError, TransactionTraceParsingError,
};

// TRANSACTION KERNEL
// ================================================================================================
Expand Down
11 changes: 10 additions & 1 deletion miden-tx/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ repository.workspace = true
rust-version.workspace = true
edition.workspace = true

[[bin]]
name = "benchmarks"
path = "src/tx_benches/mod.rs"
bench = false
doctest = false
required-features = ["executable"]

[[test]]
name = "miden-tx"
path = "tests/integration/main.rs"
Expand All @@ -20,14 +27,16 @@ path = "tests/integration/main.rs"
concurrent = ["miden-lib/concurrent", "miden-objects/concurrent", "miden-prover/concurrent", "std"]
default = ["std"]
std = ["miden-lib/std", "miden-objects/std", "miden-prover/std", "miden-verifier/std", "vm-processor/std"]
executable = ["std", "dep:clap"]

[dependencies]
clap = { version = "4.4", features = ["derive"], optional = true }
miden-lib = { package = "miden-lib", path = "../miden-lib", version = "0.3", default-features = false }
miden-objects = { package = "miden-objects", path = "../objects", version = "0.3", default-features = false }
miden-prover = { workspace = true }
miden-verifier = { workspace = true }
mock = { package = "miden-mock", path = "../mock", default-features = false }
vm-processor = { workspace = true }

[dev-dependencies]
mock = { package = "miden-mock", path = "../mock", default-features = false }
rand_chacha = { version = "0.3", default-features = false }
9 changes: 8 additions & 1 deletion miden-tx/src/executor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ pub struct TransactionExecutor<D: DataStore> {
impl<D: DataStore> TransactionExecutor<D> {
// CONSTRUCTOR
// --------------------------------------------------------------------------------------------

/// Creates a new [TransactionExecutor] instance with the specified [DataStore].
pub fn new(data_store: D) -> Self {
Self {
Expand All @@ -52,6 +53,12 @@ impl<D: DataStore> TransactionExecutor<D> {
}
}

/// Enables tracing for the created instance of [TransactionExecutor].
pub fn with_tracing(mut self) -> Self {
self.exec_options = self.exec_options.with_tracing();
self
}

// STATE MUTATORS
// --------------------------------------------------------------------------------------------

Expand Down Expand Up @@ -179,7 +186,7 @@ impl<D: DataStore> TransactionExecutor<D> {
/// Returns an error if:
/// - If required data can not be fetched from the [DataStore].
/// - If the transaction can not be compiled.
fn prepare_transaction(
pub fn prepare_transaction(
&self,
account_id: AccountId,
block_ref: u32,
Expand Down
2 changes: 1 addition & 1 deletion miden-tx/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ fn test_tx_script() {
// ================================================================================================

#[derive(Clone)]
struct MockDataStore {
pub struct MockDataStore {
pub account: Account,
pub block_header: BlockHeader,
pub block_chain: ChainMmr,
Expand Down
Loading
Loading