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

feat: debug_log_array Noir function #1057

Merged
merged 1 commit into from
Jul 13, 2023
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
42 changes: 40 additions & 2 deletions yarn-project/acir-simulator/src/client/debug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,14 @@ function applyStringFormatting(formatStr: string, args: ACVMField[]): string {
/**
* Convert an array of ACVMFields from ACVM to a formatted string.
*
* @param parameters - either one parameter representing a simple field, or two parameters when
* @param parameters - either one parameter representing a simple field or array, or two parameters when
* It's a message without args or three parameters when it's a message with arguments.
*
* @returns formatted string
*/
export function oracleDebugCallToFormattedStr(parameters: ForeignCallInput[]): string {
if (parameters.length === 1) {
return `${parameters[0][0]}`;
return processFieldOrArray(parameters[0]);
}

let formatArgs: string[] = [];
Expand All @@ -68,3 +68,41 @@ export function oracleDebugCallToFormattedStr(parameters: ForeignCallInput[]): s

return formattedMsg;
}

/**
* Processes a field or an array and returns a string representation.
* @param fieldOrArray - The field or array to be processed.
* @returns Returns the processed string representation of the field or array.
*/
function processFieldOrArray(fieldOrArray: string[]) {
if (fieldOrArray.length === 1) {
return `${fieldOrArray[0]}`;
}

// Check if all the elements start with 63 zero bytes
// --> if yes, we have an array of bytes and we print as decimal values
if (onlyBytes(fieldOrArray)) {
const decimalArray = fieldOrArray.map(element => parseInt(element, 16));
return '[' + decimalArray.join(', ') + ']';
}

return '[' + fieldOrArray.join(', ') + ']';
}

/**
* Checks if all elements in the array are valid byte representations.
* @param array - The array to be checked.
* @returns Returns `true` if all elements are valid byte representations, `false` otherwise.
* @throws Throws an error if any element has an invalid length.
*/
function onlyBytes(array: string[]): boolean {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the future, lodash#every is your friend ;-)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Damn, it has been too long since I last suggested using lodash in a PR review.

for (const element of array) {
if (element.length != 66) {
throw new Error('Invalid element length. Expected 66 chars, got ' + element.length + ' chars.');
}
if (!element.startsWith('0x00000000000000000000000000000000000000000000000000000000000000')) {
return false;
}
}
return true;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ fn debug_log_oracle<T, N>(_msg: T, _num_args: Field) -> Field {}
fn debug_log_format_oracle<T, N>(_msg: T, _args: [Field; N], _num_args: Field) -> Field {}
#[oracle(debugLog)]
fn debug_log_field_oracle(_field: Field) -> Field {}
#[oracle(debugLog)]
fn debug_log_array_oracle<T, N>(_arbitrary_array: [T;N]) -> Field {}

/// NOTE: call this with a str<N> msg of length > 1
/// Example:
Expand All @@ -30,3 +32,9 @@ unconstrained fn debug_log_format<T, N>(msg: T, args: [Field; N]) {
unconstrained fn debug_log_field(field: Field) {
assert(debug_log_field_oracle(field) == 0);
}

/// Example:
/// `debug_log_array(my_array);`
unconstrained fn debug_log_array<T, N>(arbitrary_array: [T; N]) {
assert(debug_log_array_oracle(arbitrary_array) == 0);
}