Skip to content
This repository has been archived by the owner on Apr 9, 2024. It is now read-only.

feat: add method to generate the new Brillig opcode from UnresolvedBrilligCall #363

Merged
merged 4 commits into from
Jun 12, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
4 changes: 3 additions & 1 deletion acir/src/circuit/brillig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ pub enum BrilligOutputs {
pub struct Brillig {
pub inputs: Vec<BrilligInputs>,
pub outputs: Vec<BrilligOutputs>,
/// Results of oracles/functions external to brillig like a database read
/// Results of oracles/functions external to brillig like a database read.
// Each element of this vector corresponds to a single foreign call but may contain several values.
TomAFrench marked this conversation as resolved.
Show resolved Hide resolved
pub foreign_call_results: Vec<ForeignCallResult>,
/// The Brillig VM bytecode to be executed by this ACIR opcode.
pub bytecode: Vec<brillig_vm::Opcode>,
/// Predicate of the Brillig execution - indicates if it should be skipped
pub predicate: Option<Expression>,
Expand Down
25 changes: 20 additions & 5 deletions acvm/src/pwg/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use crate::{Language, PartialWitnessGenerator};
use acir::{
brillig_vm::ForeignCallResult,
circuit::brillig::Brillig,
circuit::opcodes::{Opcode, OracleData},
native_types::{Expression, Witness, WitnessMap},
Expand Down Expand Up @@ -36,7 +37,12 @@ pub enum PartialWitnessGeneratorStatus {

/// The `PartialWitnessGenerator` has encountered a request for [oracle data][Opcode::Oracle] or a Brillig [foreign call][acir::brillig_vm::Opcode::ForeignCall].
///
/// The caller must resolve these opcodes externally and insert the results into the intermediate witness.
/// Both of these opcodes require information from outside of the ACVM to be inserted before restarting execution.
/// [`Opcode::Oracle`] and [`Opcode::Brillig`] opcodes require the return values to be inserted slightly differently.
/// `Oracle` opcodes expect their return values to be written directly into the witness map whereas a `Brillig` foreign call
/// result is inserted into the `Brillig` opcode which made the call using [`UnresolvedBrilligCall::resolve_foreign_call`].
/// (Note: this means that the updated opcode must then be passed back into the ACVM to be processed further.)
///
/// Once this is done, the `PartialWitnessGenerator` can be restarted to solve the remaining opcodes.
RequiresOracleData {
required_oracle_data: Vec<OracleData>,
Expand Down Expand Up @@ -253,16 +259,25 @@ pub fn insert_value(
#[derive(Debug, PartialEq, Clone)]
pub struct UnresolvedBrilligCall {
/// The current Brillig VM process that has been paused.
/// This process will be updated by the caller after resolving a foreign call's outputs.
/// This process will be updated by the caller after resolving a foreign call's result.
///
/// The [foreign call's result][acir::brillig_vm::ForeignCallResult] should be appended to this current [Brillig call][Brillig].
/// The [PartialWitnessGenerator] can then be restarted with an updated [Brillig opcode][Opcode::Brillig]
/// to solve the remaining Brillig VM process as well as the remaining ACIR opcodes.
/// This can be done using [`UnresolvedBrilligCall::resolve_foreign_call`].
pub brillig: Brillig,
/// Inputs for a pending foreign call required to restart bytecode processing.
pub foreign_call_wait_info: brillig::ForeignCallWaitInfo,
}

impl UnresolvedBrilligCall {
/// Inserts the [foreign call's result][acir::brillig_vm::ForeignCallResult] into the calling [`Brillig` opcode][Brillig].
///
/// The [ACVM][solve] can then be restarted with the updated [Brillig opcode][Opcode::Brillig]
/// to solve the remaining Brillig VM process as well as the remaining ACIR opcodes.
pub fn resolve_foreign_call(mut self, foreign_call_result: ForeignCallResult) -> Brillig {
self.brillig.foreign_call_results.push(foreign_call_result);
self.brillig
}
}

#[deprecated(
note = "For backwards compatibility, this method allows you to derive _sensible_ defaults for opcode support based on the np language. \n Backends should simply specify what they support."
)]
Expand Down
5 changes: 4 additions & 1 deletion brillig_vm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,12 @@ pub enum VMStatus {
},
}

/// Represents the output of a [foreign call][Opcode::ForeignCall].
///
/// See [`VMStatus::ForeignCallWait`] for more information.
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Clone)]
pub struct ForeignCallResult {
/// Resolved foreign call values
/// Resolved output values of the foreign call.
pub values: Vec<Value>,
}

Expand Down