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

Stack Output Parser for Transaction Script Results #1161

Open
JordyRo1 opened this issue Feb 17, 2025 · 3 comments
Open

Stack Output Parser for Transaction Script Results #1161

JordyRo1 opened this issue Feb 17, 2025 · 3 comments
Labels
enhancement New feature or request
Milestone

Comments

@JordyRo1
Copy link

JordyRo1 commented Feb 17, 2025

Feature description

We need to implement functionality to parse and load the stack output from transaction script executions into a Rust data structure. This will make stack values accessible and manipulable as Rust entities.

This feature might be already existing.I would appreciate if you can provide any documentation/code, that might help solve this.

Current behavior

Currently, when executing a transaction script like:

use.oracle_component::oracle_module
use.std::sys

begin
    push.{pair}
    call.oracle_module::get_median
    debug.stack
    exec.sys::truncate_stack
end

The get_median function returns a price value that is pushed onto the stack. The debug.stack output shows a 20-element stack with the price value (98179860000) at index 0, followed by zeros:
Stack state before step 7234:

├──  0: 98179860000
├──  1: 0
[...]
└── 19: 0

Why is this feature needed?

Implement functionality to:

  • Parse the stack output into a Rust data structure (e.g., Vec or similar appropriate type)
  • Preserve the order and values of stack elements
  • Make the stack data easily accessible for further processing in Rust
@JordyRo1 JordyRo1 added the enhancement New feature or request label Feb 17, 2025
@bobbinth
Copy link
Contributor

Thank you for such a detailed description! I do have a couple of clarifying questions:

use.oracle_component::oracle_module
use.std::sys

begin
push.{pair}
call.oracle_module::get_median
debug.stack
exec.sys::truncate_stack
end

Transaction scripts are usually meant to be execute as a part of a transaction to update account state, create notes etc. The above script (as currently written) just reads the account state and puts the data on the stack - so, it won't really have a meaningful effect on a transaction. So, I'm curious if you are planning to execute it as a part of a transaction or as a "stand-alone" program.

If the intent is to run it as a stand-alone program, is this mostly for testing/debugging purposes? Or is the result meant to be used for something meaningful?

@JordyRo1
Copy link
Author

The get-entry functionality serves as a "view" function, allowing users to query specific functions within the oracle contract. When called, it performs the necessary computations and outputs the results onto the stack.
We primarily used this script for testing purposes. However, potential users might want to use the Rust CLI to retrieve the price and have it available directly as a rust variable and not in the stack. While this use case is hypothetical, we wanted to ensure the functionality is available if needed. Do you think this is relevant, or should we just assume that potential users will just use the value from the stack ?

@bobbinth
Copy link
Contributor

So, if I understood correctly: a user may want to execute an arbitrary script against an account (kind of like transaction script but with the intent to only read the state of the account rather than update it) and get the results. We don't currently have something exactly like this, but I think this could be a very useful functionality to provide.

To achieve this, we probably would need to do the following:

Add a new method to TransactionExecutor - something like this:

pub fn execute_program(
    &self,
    account_id: AccountId,
    block_ref: BlockNumber,
    tx_script: TransactionScript,
    advice_inputs: AdviceInputs,
) -> Result<[Felt; 16], TransactionExecutorError>

This would basically run the transaction kernel prologue, then run the transaction script and return the top of the stack after the transaction script completes. (we could probably use this method in the test code quite a bit).

Then, to make this more accessible, we'll need to add some functionality to the client/CLI. On the CLI side it could be something like an exec command:

miden exec --account <account_id> --script <path to masm file> --inputs <path to inputs file>

This would compile the script and execute it agains the specified account using TransactionExecutor::execute_program() method described above.

cc @PhilippGackstatter, @igamigo (we probably should create an issue for this in miden-client), @Fumuran.

@bobbinth bobbinth added this to the v0.9 milestone Feb 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants