AleoNet / snarkVM

A Virtual Machine for Zero-Knowledge Executions

Home Page:https://snarkvm.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Feature] Allow use of evaluate_function for nested program calls in `CallStack::PackageRun`

vicsn opened this issue · comments

🚀 Feature

We currently call execute_function for every nested call in a program, which can be quite costly. We avoid this in CallStack::CheckDeployment by only executing the top level request, we may be able to avoid it in CallStack::PackageRun by using evaluate_function.

You can test this by running cargo test --features timer package::clean::tests::test_clean_with_import -- --nocapture. You will see some obstacles. When always using execute_function, we explicitly load new registers for the new nested call:

             Lap (Stack::execute_function, Verify the circuit request) ...............................................63.872ms
             Lap (Stack::execute_function, Initialize the registers) ...............................................20.250µs
✅ Request              (Constant: 3359, Public: 9, Private: 12626, Constraints: 12632, NonZeros: (30146, 42252, 16847))
             Lap (Stack::execute_function, Store the inputs) ..............................................448.209µs
             Start (Call::execute)          ...... [synthesizer/process/src/stack/call/mod.rs L145]
                 Lap (Call::execute, Retrieve the substack and resource) ...............................................15.917µs
                 Lap (Call::execute, Execute the function) ................................................4.625µs
                 Start (Stack::execute_function) ....... [synthesizer/process/src/stack/execute.rs L140]

However, when using evaluate_function for nested calls, we do not properly propagate the program information:

             Lap (Stack::evaluate_function, Verify the request) ..............................................878.625µs
             Lap (Stack::evaluate_function, Store the inputs) ................................................5.875µs
             Start (Call::evaluate)         ....... [synthesizer/process/src/stack/call/mod.rs L62]
                 Lap (Call::evaluate, Retrieved the substack and resource) ................................................3.250µs
                 Start (Stack::evaluate_function) ...... [synthesizer/process/src/stack/evaluate.rs L104]
                     Lap (Stack::evaluate_function, Retrieve the next request) ................................................1.667µs
                 Finish (Stack::evaluate_function)                  ..................3.500µs
             Finish (Call::evaluate)                            .................11.458µs
         Finish (Stack::evaluate_function)                  ..................1.234ms
     Finish (Call::execute)                             ..................4.498ms
 Finish (Stack::execute_function)                   .................72.942ms
thread 'package::run::tests::test_run_with_nested_imports' panicked at 'called `Result::unwrap()` on an `Err` value: Failed to execute instruction (call parent.aleo/wrapper_mint r0 r1 into r2;): Failed to evaluate instruction (call child.aleo/mint r0 r1 into r2;): Function 'wrapper_mint' is not defined.', vm/package/run.rs:137:110

See this PR for more background: https://github.com/AleoHQ/snarkVM/pull/2285

This is low priority because package_run is only run client-side or on our CI.