Skip to content
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
20 changes: 20 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions acvm-repo/acir/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ fxhash.workspace = true
criterion.workspace = true
pprof.workspace = true
num-bigint.workspace = true
insta = "1.42.2"

acir = { path = ".", features = ["arb"] } # Self to turn on `arb`.

Expand Down
44 changes: 43 additions & 1 deletion acvm-repo/acir/src/circuit/opcodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,11 @@
match databus {
BlockType::Memory => write!(f, "INIT ")?,
BlockType::CallData(id) => write!(f, "INIT CALLDATA {} ", id)?,
BlockType::ReturnData => write!(f, "INIT RETURNDATA ")?,

Check warning on line 176 in acvm-repo/acir/src/circuit/opcodes.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (RETURNDATA)
}
write!(f, "(id: {}, len: {}) ", block_id.0, init.len())
let witnesses =
init.iter().map(|w| format!("_{}", w.0)).collect::<Vec<String>>().join(", ");
write!(f, "(id: {}, len: {}, witnesses: [{witnesses}])", block_id.0, init.len())
}
// We keep the display for a BrilligCall and circuit Call separate as they
// are distinct in their functionality and we should maintain this separation for debugging.
Expand Down Expand Up @@ -204,3 +206,43 @@
std::fmt::Display::fmt(self, f)
}
}

#[cfg(test)]
mod tests {
use acir_field::FieldElement;

use crate::{
circuit::opcodes::{BlackBoxFuncCall, BlockId, BlockType, FunctionInput},
native_types::Witness,
};

use super::Opcode;

#[test]
fn mem_init_display_snapshot() {
let mem_init: Opcode<FieldElement> = Opcode::MemoryInit {
block_id: BlockId(42),
init: (0..10u32).map(Witness).collect(),
block_type: BlockType::Memory,
};

insta::assert_snapshot!(
mem_init.to_string(),
@"INIT (id: 42, len: 10, witnesses: [_0, _1, _2, _3, _4, _5, _6, _7, _8, _9])"
);
}

#[test]
fn blackbox_snapshot() {
let xor: Opcode<FieldElement> = Opcode::BlackBoxFuncCall(BlackBoxFuncCall::XOR {
lhs: FunctionInput::witness(0.into(), 32),
rhs: FunctionInput::witness(1.into(), 32),
output: Witness(3),
});

insta::assert_snapshot!(
xor.to_string(),
@"BLACKBOX::XOR [(_0, 32), (_1, 32)] [_3]"
);
}
}
87 changes: 22 additions & 65 deletions acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,12 @@ impl<F: AcirField> FunctionInput<F> {
impl<F: std::fmt::Display> std::fmt::Display for FunctionInput<F> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match &self.input {
ConstantOrWitnessEnum::Constant(constant) => write!(f, "{constant}"),
ConstantOrWitnessEnum::Witness(witness) => write!(f, "{}", witness.0),
ConstantOrWitnessEnum::Constant(constant) => {
write!(f, "({constant}, {})", self.num_bits)
}
ConstantOrWitnessEnum::Witness(witness) => {
write!(f, "(_{}, {})", witness.0, self.num_bits)
}
}
}
}
Expand Down Expand Up @@ -463,80 +467,33 @@ impl<F: Copy> BlackBoxFuncCall<F> {
}
}

const ABBREVIATION_LIMIT: usize = 5;

fn get_inputs_string<F: std::fmt::Display>(inputs: &[FunctionInput<F>]) -> String {
// Once a vectors length gets above this limit,
// instead of listing all of their elements, we use ellipses
// to abbreviate them
let should_abbreviate_inputs = inputs.len() <= ABBREVIATION_LIMIT;

if should_abbreviate_inputs {
let mut result = String::new();
for (index, inp) in inputs.iter().enumerate() {
result += &format!("({})", inp);
// Add a comma, unless it is the last entry
if index != inputs.len() - 1 {
result += ", ";
}
}
result
} else {
let first = inputs.first().unwrap();
let last = inputs.last().unwrap();

let mut result = String::new();
result += &format!("({})...({})", first, last,);

result
}
}

fn get_outputs_string(outputs: &[Witness]) -> String {
let should_abbreviate_outputs = outputs.len() <= ABBREVIATION_LIMIT;

if should_abbreviate_outputs {
let mut result = String::new();
for (index, output) in outputs.iter().enumerate() {
result += &format!("_{}", output.witness_index());
// Add a comma, unless it is the last entry
if index != outputs.len() - 1 {
result += ", ";
}
}
result
} else {
let first = outputs.first().unwrap();
let last = outputs.last().unwrap();

let mut result = String::new();
result += &format!("(_{},...,_{})", first.witness_index(), last.witness_index());
result
}
}

impl<F: std::fmt::Display + Copy> std::fmt::Display for BlackBoxFuncCall<F> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let uppercase_name = self.name().to_uppercase();
write!(f, "BLACKBOX::{uppercase_name} ")?;
// INPUTS
write!(f, "[")?;

let inputs_str = get_inputs_string(&self.get_inputs_vec());
let inputs_str = &self
.get_inputs_vec()
.iter()
.map(|i| i.to_string())
.collect::<Vec<String>>()
.join(", ");

write!(f, "{inputs_str}")?;
write!(f, "] ")?;
write!(f, "[{inputs_str}]")?;

// OUTPUTS
write!(f, "[ ")?;
write!(f, " ")?;

let outputs_str = get_outputs_string(&self.get_outputs_vec());

write!(f, "{outputs_str}")?;
// OUTPUTS

write!(f, "]")?;
let outputs_str = &self
.get_outputs_vec()
.iter()
.map(|i| format!("_{}", i.0))
.collect::<Vec<String>>()
.join(", ");

write!(f, "")
write!(f, "[{outputs_str}]")
}
}

Expand Down
1 change: 1 addition & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@
"indexmap",
"injective",
"Inlines",
"insta",
"instrumenter",
"interner",
"interners",
Expand Down
Loading