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

fix: decode databus return values #6095

Merged
merged 6 commits into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
7 changes: 6 additions & 1 deletion compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,12 @@ impl<'a> Context<'a> {
warnings.extend(self.acir_context.warnings.clone());

// Add the warnings from the alter Ssa passes
Ok(self.acir_context.finish(input_witness, return_witnesses, warnings))
Ok(self.acir_context.finish(
input_witness,
// Don't embed databus return witnesses into the circuit.
if self.data_bus.return_data.is_some() { Vec::new() } else { return_witnesses },
warnings,
))
}

fn initialize_databus(
Expand Down
1 change: 1 addition & 0 deletions tooling/noir_js/scripts/compile_test_programs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ nargo --program-dir ./test/noir_compiled_examples/assert_lt compile --force
nargo --program-dir ./test/noir_compiled_examples/assert_msg_runtime compile --force
nargo --program-dir ./test/noir_compiled_examples/fold_fibonacci compile --force
nargo --program-dir ./test/noir_compiled_examples/assert_raw_payload compile --force
nargo --program-dir ./test/noir_compiled_examples/databus compile --force
47 changes: 9 additions & 38 deletions tooling/noir_js/test/node/execute.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import assert_lt_json from '../noir_compiled_examples/assert_lt/target/assert_lt
import assert_msg_json from '../noir_compiled_examples/assert_msg_runtime/target/assert_msg_runtime.json' assert { type: 'json' };
import fold_fibonacci_json from '../noir_compiled_examples/fold_fibonacci/target/fold_fibonacci.json' assert { type: 'json' };
import assert_raw_payload_json from '../noir_compiled_examples/assert_raw_payload/target/assert_raw_payload.json' assert { type: 'json' };
import databus_json from '../noir_compiled_examples/databus/target/databus.json' assert { type: 'json' };

import { Noir, ErrorWithPayload } from '@noir-lang/noir_js';
import { CompiledCircuit } from '@noir-lang/types';
Expand All @@ -10,6 +11,7 @@ import { expect } from 'chai';
const assert_lt_program = assert_lt_json as CompiledCircuit;
const assert_msg_runtime = assert_msg_json as CompiledCircuit;
const fold_fibonacci_program = fold_fibonacci_json as CompiledCircuit;
const databus_program = databus_json as CompiledCircuit;

it('executes a single-ACIR program correctly', async () => {
const inputs = {
Expand Down Expand Up @@ -86,46 +88,15 @@ it('successfully executes a program with multiple acir circuits', async () => {
const inputs = {
x: '10',
};
try {
await new Noir(fold_fibonacci_program).execute(inputs);
} catch (error) {
const knownError = error as Error;
expect(knownError.message).to.equal('Circuit execution failed: Error: Cannot satisfy constraint');
}
});

it('successfully executes a program with multiple acir circuits', async () => {
const inputs = {
x: '10',
};
try {
await new Noir(fold_fibonacci_program).execute(inputs);
} catch (error) {
const knownError = error as Error;
expect(knownError.message).to.equal('Circuit execution failed: Error: Cannot satisfy constraint');
}
});

it('successfully executes a program with multiple acir circuits', async () => {
const inputs = {
x: '10',
};
try {
await new Noir(fold_fibonacci_program).execute(inputs);
} catch (error) {
const knownError = error as Error;
expect(knownError.message).to.equal('Circuit execution failed: Error: Cannot satisfy constraint');
}
expect(() => new Noir(fold_fibonacci_program).execute(inputs)).to.not.throw();
});

it('successfully executes a program with multiple acir circuits', async () => {
it('successfully decodes the return values from a program using the databus', async () => {
const inputs = {
x: '10',
x: '3',
y: '4',
z: [1, 2, 3, 4],
};
try {
await new Noir(fold_fibonacci_program).execute(inputs);
} catch (error) {
const knownError = error as Error;
expect(knownError.message).to.equal('Circuit execution failed: Error: Cannot satisfy constraint');
}
const { returnValue } = await new Noir(databus_program).execute(inputs);
expect(returnValue).to.be.eq('0x09');
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[package]
name = "databus"
type = "bin"
authors = [""]
[dependencies]
12 changes: 12 additions & 0 deletions tooling/noir_js/test/noir_compiled_examples/databus/src/main.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
fn main(mut x: u32, y: call_data(0) u32, z: call_data(0) [u32; 4]) -> return_data u32 {
let a = z[x];
unsafe {
a + foo(y)
}
}

// Use an unconstrained function to force the compiler to avoid inlining
unconstrained fn foo(x: u32) -> u32 {
x + 1
}

17 changes: 7 additions & 10 deletions tooling/noirc_abi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,12 @@ impl Abi {

/// Returns whether any values are needed to be made public for verification.
pub fn has_public_inputs(&self) -> bool {
self.return_type.is_some() || self.parameters.iter().any(|param| param.is_public())
let has_public_args = self.parameters.iter().any(|param| param.is_public());
let has_public_return = self
.return_type
.as_ref()
.map_or(false, |typ| matches!(typ.visibility, AbiVisibility::Public));
has_public_args || has_public_return
}

/// Returns `true` if the ABI contains no parameters or return value.
Expand Down Expand Up @@ -346,15 +351,7 @@ impl Abi {
.copied()
})
{
// We do not return value for the data bus.
if return_type.visibility == AbiVisibility::DataBus {
None
} else {
Some(decode_value(
&mut return_witness_values.into_iter(),
&return_type.abi_type,
)?)
}
Some(decode_value(&mut return_witness_values.into_iter(), &return_type.abi_type)?)
} else {
// Unlike for the circuit inputs, we tolerate not being able to find the witness values for the return value.
// This is because the user may be decoding a partial witness map for which is hasn't been calculated yet.
Expand Down
Loading