-
Notifications
You must be signed in to change notification settings - Fork 121
Add hooks to enable TX debugging #2574
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
base: next
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| use alloc::collections::BTreeSet; | ||
| use alloc::sync::Arc; | ||
| use core::marker::PhantomData; | ||
|
|
||
| use miden_processor::advice::AdviceInputs; | ||
| use miden_processor::{ExecutionError, FastProcessor, StackInputs}; | ||
|
|
@@ -40,6 +41,9 @@ pub use notes_checker::{ | |
| NoteConsumptionInfo, | ||
| }; | ||
|
|
||
| mod program_executor; | ||
| pub use program_executor::ProgramExecutor; | ||
|
|
||
| // TRANSACTION EXECUTOR | ||
| // ================================================================================================ | ||
|
|
||
|
|
@@ -52,11 +56,18 @@ pub use notes_checker::{ | |
| /// The transaction executor uses dynamic dispatch with trait objects for the [DataStore] and | ||
| /// [TransactionAuthenticator], allowing it to be used with different backend implementations. | ||
| /// At the moment of execution, the [DataStore] is expected to provide all required MAST nodes. | ||
| pub struct TransactionExecutor<'store, 'auth, STORE: 'store, AUTH: 'auth> { | ||
| pub struct TransactionExecutor< | ||
| 'store, | ||
| 'auth, | ||
| STORE: 'store, | ||
| AUTH: 'auth, | ||
| EXEC: ProgramExecutor = FastProcessor, | ||
| > { | ||
| data_store: &'store STORE, | ||
| authenticator: Option<&'auth AUTH>, | ||
| source_manager: Arc<dyn SourceManagerSync>, | ||
| exec_options: ExecutionOptions, | ||
| _executor: PhantomData<EXEC>, | ||
| } | ||
|
|
||
| impl<'store, 'auth, STORE, AUTH> TransactionExecutor<'store, 'auth, STORE, AUTH> | ||
|
|
@@ -71,9 +82,13 @@ where | |
| /// | ||
| /// The created executor will not have the authenticator or source manager set, and tracing and | ||
| /// debug mode will be turned off. | ||
| /// | ||
| /// By default, the executor uses [`FastProcessor`](miden_processor::FastProcessor) for program | ||
| /// execution. Use [`with_program_executor`](Self::with_program_executor) to plug in a | ||
| /// different execution engine. | ||
| pub fn new(data_store: &'store STORE) -> Self { | ||
| const _: () = assert!(MIN_TX_EXECUTION_CYCLES <= MAX_TX_EXECUTION_CYCLES); | ||
| TransactionExecutor { | ||
| Self { | ||
| data_store, | ||
| authenticator: None, | ||
| source_manager: Arc::new(DefaultSourceManager::default()), | ||
|
|
@@ -85,6 +100,30 @@ where | |
| false, | ||
| ) | ||
| .expect("Must not fail while max cycles is more than min trace length"), | ||
| _executor: PhantomData, | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl<'store, 'auth, STORE, AUTH, EXEC> TransactionExecutor<'store, 'auth, STORE, AUTH, EXEC> | ||
| where | ||
| STORE: DataStore + 'store + Sync, | ||
| AUTH: TransactionAuthenticator + 'auth + Sync, | ||
| EXEC: ProgramExecutor, | ||
| { | ||
| /// Replaces the transaction program executor with a different implementation. | ||
| /// | ||
| /// This allows plugging in alternative execution engines while preserving the rest of the | ||
| /// transaction executor configuration. | ||
| pub fn with_program_executor<EXEC2: ProgramExecutor>( | ||
| self, | ||
| ) -> TransactionExecutor<'store, 'auth, STORE, AUTH, EXEC2> { | ||
| TransactionExecutor::<'store, 'auth, STORE, AUTH, EXEC2> { | ||
| data_store: self.data_store, | ||
| authenticator: self.authenticator, | ||
| source_manager: self.source_manager, | ||
| exec_options: self.exec_options, | ||
| _executor: PhantomData, | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -186,8 +225,7 @@ where | |
|
|
||
| // instantiate the processor in debug mode only when debug mode is specified via execution | ||
| // options; this is important because in debug mode execution is almost 100x slower | ||
| let processor = | ||
| FastProcessor::new_with_options(stack_inputs, advice_inputs, self.exec_options); | ||
| let processor = EXEC::new(stack_inputs, advice_inputs, self.exec_options); | ||
|
|
||
| let output = processor | ||
| .execute(&TransactionKernel::main(), &mut host) | ||
|
|
@@ -233,7 +271,7 @@ where | |
|
|
||
| let (mut host, stack_inputs, advice_inputs) = self.prepare_transaction(&tx_inputs).await?; | ||
|
|
||
| let processor = FastProcessor::new(stack_inputs).with_advice(advice_inputs); | ||
| let processor = EXEC::new(stack_inputs, advice_inputs, ExecutionOptions::default()); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same comment as above. |
||
| let output = processor | ||
| .execute(&TransactionKernel::tx_script_main(), &mut host) | ||
| .await | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,6 @@ | ||
| use alloc::collections::BTreeMap; | ||
| use alloc::vec::Vec; | ||
|
|
||
| use miden_processor::FastProcessor; | ||
| use miden_processor::advice::AdviceInputs; | ||
| use miden_protocol::account::AccountId; | ||
| use miden_protocol::block::BlockNumber; | ||
|
|
@@ -15,7 +14,7 @@ use miden_protocol::transaction::{ | |
| }; | ||
| use miden_standards::note::{NoteConsumptionStatus, StandardNote}; | ||
|
|
||
| use super::TransactionExecutor; | ||
| use super::{ExecutionOptions, ProgramExecutor, TransactionExecutor}; | ||
| use crate::auth::TransactionAuthenticator; | ||
| use crate::errors::TransactionCheckerError; | ||
| use crate::executor::map_execution_error; | ||
|
|
@@ -73,15 +72,18 @@ impl NoteConsumptionInfo { | |
| /// The check is performed using the [NoteConsumptionChecker::check_notes_consumability] procedure. | ||
| /// Essentially runs the transaction to make sure that provided input notes could be consumed by the | ||
| /// account. | ||
| pub struct NoteConsumptionChecker<'a, STORE, AUTH>(&'a TransactionExecutor<'a, 'a, STORE, AUTH>); | ||
| pub struct NoteConsumptionChecker<'a, STORE, AUTH, EXEC: ProgramExecutor>( | ||
| &'a TransactionExecutor<'a, 'a, STORE, AUTH, EXEC>, | ||
| ); | ||
|
|
||
| impl<'a, STORE, AUTH> NoteConsumptionChecker<'a, STORE, AUTH> | ||
| impl<'a, STORE, AUTH, EXEC> NoteConsumptionChecker<'a, STORE, AUTH, EXEC> | ||
| where | ||
| STORE: DataStore + Sync, | ||
| AUTH: TransactionAuthenticator + Sync, | ||
| EXEC: ProgramExecutor, | ||
| { | ||
| /// Creates a new [`NoteConsumptionChecker`] instance with the given transaction executor. | ||
| pub fn new(tx_executor: &'a TransactionExecutor<'a, 'a, STORE, AUTH>) -> Self { | ||
| pub fn new(tx_executor: &'a TransactionExecutor<'a, 'a, STORE, AUTH, EXEC>) -> Self { | ||
| NoteConsumptionChecker(tx_executor) | ||
| } | ||
|
|
||
|
|
@@ -337,7 +339,7 @@ where | |
| .await | ||
| .map_err(TransactionCheckerError::TransactionPreparation)?; | ||
|
|
||
| let processor = FastProcessor::new(stack_inputs).with_advice(advice_inputs); | ||
| let processor = EXEC::new(stack_inputs, advice_inputs, ExecutionOptions::default()); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not related to this PR, but I wonder if the options should be configured somehow (i.e., we shouldn't be using just the default options). cc @PhilippGackstatter. |
||
| let result = processor | ||
| .execute(&TransactionKernel::main(), &mut host) | ||
| .await | ||
|
|
||
bobbinth marked this conversation as resolved.
Show resolved
Hide resolved
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| use miden_processor::advice::AdviceInputs; | ||
| use miden_processor::{ | ||
| ExecutionError, | ||
| ExecutionOptions, | ||
| ExecutionOutput, | ||
| FastProcessor, | ||
| FutureMaybeSend, | ||
| Host, | ||
| Program, | ||
| StackInputs, | ||
| }; | ||
|
|
||
| /// A transaction-scoped program executor used by | ||
| /// [`TransactionExecutor`](super::TransactionExecutor). | ||
| /// | ||
| /// TODO: Move this trait into `miden-vm` once the executor boundary is | ||
| /// consolidated there. | ||
| pub trait ProgramExecutor { | ||
bobbinth marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| /// Create a new executor configured with the provided transaction inputs and options. | ||
| fn new( | ||
| stack_inputs: StackInputs, | ||
| advice_inputs: AdviceInputs, | ||
| options: ExecutionOptions, | ||
| ) -> Self | ||
| where | ||
| Self: Sized; | ||
|
|
||
| /// Execute the provided program against the given host. | ||
| fn execute<H: Host + Send>( | ||
| self, | ||
| program: &Program, | ||
| host: &mut H, | ||
| ) -> impl FutureMaybeSend<Result<ExecutionOutput, ExecutionError>>; | ||
| } | ||
|
|
||
| impl ProgramExecutor for FastProcessor { | ||
| fn new( | ||
| stack_inputs: StackInputs, | ||
| advice_inputs: AdviceInputs, | ||
| options: ExecutionOptions, | ||
| ) -> Self { | ||
| FastProcessor::new_with_options(stack_inputs, advice_inputs, options) | ||
| } | ||
|
|
||
| fn execute<H: Host + Send>( | ||
| self, | ||
| program: &Program, | ||
| host: &mut H, | ||
| ) -> impl FutureMaybeSend<Result<ExecutionOutput, ExecutionError>> { | ||
| FastProcessor::execute(self, program, host) | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.