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: Flatten public inputs according to their index in numerial rather than ascii order #3605

Merged
merged 3 commits into from
Nov 28, 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
27 changes: 27 additions & 0 deletions .github/workflows/test-js-packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,32 @@ jobs:
- name: Run browser tests
run: yarn workspace @noir-lang/noirc_abi test:browser

test-noir-js-backend-barretenberg:
needs: [build-noirc-abi]
name: noir-js-backend-barretenberg
runs-on: ubuntu-latest
timeout-minutes: 30

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Download wasm package artifact
uses: actions/download-artifact@v3
with:
name: noirc_abi_wasm
path: ./tooling/noirc_abi_wasm

- name: Install Yarn dependencies
uses: ./.github/actions/setup

- name: Build noir_js_types
run: yarn workspace @noir-lang/types build
kevaundray marked this conversation as resolved.
Show resolved Hide resolved

- name: Run barretenberg wrapper tests
run: |
yarn workspace @noir-lang/backend_barretenberg test

test-noir-js:
needs: [build-acvm-js, build-noirc-abi]
name: Noir JS
Expand Down Expand Up @@ -401,6 +427,7 @@ jobs:
- test-acvm_js-node
- test-acvm_js-browser
- test-noirc-abi
- test-noir-js-backend-barretenberg
- test-noir-js
- test-source-resolver
- test-noir-wasm
Expand Down
11 changes: 11 additions & 0 deletions tooling/noir_js_backend_barretenberg/.mocharc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"require": "ts-node/register",
"loader": "ts-node/esm",
"extensions": [
"ts",
"cjs"
],
"spec": [
"test/**/*.test.ts*"
]
}
4 changes: 4 additions & 0 deletions tooling/noir_js_backend_barretenberg/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"generate:package": "bash ./fixup.sh",
"build": "yarn clean && tsc && tsc -p ./tsconfig.cjs.json && yarn generate:package",
"clean": "rm -rf ./lib",
"test": "mocha --timeout 25000 --exit --config ./.mocharc.json",
"prettier": "prettier 'src/**/*.ts'",
"prettier:fix": "prettier --write 'src/**/*.ts' 'test/**/*.ts'",
"nightly:version": "jq --arg new_version \"-$(git rev-parse --short HEAD)$1\" '.version = .version + $new_version' package.json > package-tmp.json && mv package-tmp.json package.json",
Expand All @@ -39,9 +40,12 @@
"devDependencies": {
"@types/node": "^20.6.2",
"@types/prettier": "^3",
"chai": "^4.3.8",
"eslint": "^8.50.0",
"eslint-plugin-prettier": "^5.0.0",
"mocha": "^10.2.0",
"prettier": "3.0.3",
"ts-node": "^10.9.1",
"typescript": "5.1.5"
}
}
6 changes: 4 additions & 2 deletions tooling/noir_js_backend_barretenberg/src/public_inputs.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Abi, WitnessMap } from '@noir-lang/types';

export function flattenPublicInputs(publicInputs: WitnessMap): string[] {
const publicInputIndices = [...publicInputs.keys()].sort();
const publicInputIndices = [...publicInputs.keys()].sort((a, b) => a - b);
kevaundray marked this conversation as resolved.
Show resolved Hide resolved
const flattenedPublicInputs = publicInputIndices.map((index) => publicInputs.get(index) as string);
return flattenedPublicInputs;
}
Expand Down Expand Up @@ -31,7 +31,9 @@ export function deflattenPublicInputs(flattenedPublicInputs: Uint8Array, abi: Ab

// We now have an array of witness indices which have been deduplicated and sorted in ascending order.
// The elements of this array should correspond to the elements of `flattenedPublicInputs` so that we can build up a `WitnessMap`.
const public_input_witnesses = [...new Set(public_parameter_witnesses.concat(return_value_witnesses))].sort();
const public_input_witnesses = [...new Set(public_parameter_witnesses.concat(return_value_witnesses))].sort(
(a, b) => a - b,
);

const publicInputs: WitnessMap = new Map();
public_input_witnesses.forEach((witness_index, index) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { Abi } from '@noir-lang/types';
import { expect } from 'chai';
import { flattenPublicInputsAsArray, deflattenPublicInputs, flattenPublicInputs } from '../src/public_inputs.js';

const abi: Abi = {
parameters: [
{
kevaundray marked this conversation as resolved.
Show resolved Hide resolved
name: 'array_with_returned_element',
type: {
kind: 'array',
type: {
kind: 'field',
},
length: 10,
},
visibility: 'private',
},
{
name: 'pub_field',
type: {
kind: 'field',
},
visibility: 'public',
},
],
param_witnesses: {
array_with_returned_element: [
{
start: 1,
end: 11,
},
],
pub_field: [
{
start: 11,
end: 12,
},
],
},
return_type: {
kind: 'tuple',
fields: [
{
kind: 'field',
},
{
kind: 'field',
},
{
kind: 'field',
},
],
},
return_witnesses: [2, 13, 13],
};

it('flattens a witness map in order of its witness indices', async () => {
// Note that these are not in ascending order. This means that if we read from `witness_map` in insertion order
// then the witness values will be sorted incorrectly.
const public_input_indices = [2, 13, 11];

const witness_map = new Map(
public_input_indices.map((witness_index) => [
witness_index,
'0x' + BigInt(witness_index).toString(16).padStart(64, '0'),
]),
);

const flattened_public_inputs = flattenPublicInputs(witness_map);
expect(flattened_public_inputs).to.be.deep.eq([
'0x0000000000000000000000000000000000000000000000000000000000000002',
'0x000000000000000000000000000000000000000000000000000000000000000b',
'0x000000000000000000000000000000000000000000000000000000000000000d',
]);
});

it('recovers the original witness map when deflattening a public input array', async () => {
// Note that these are not in ascending order. This means that if we read from `witness_map` in insertion order
// then the witness values will be sorted incorrectly.
const public_input_indices = [2, 13, 11];

const witness_map = new Map(
public_input_indices.map((witness_index) => [
witness_index,
'0x' + BigInt(witness_index).toString(16).padStart(64, '0'),
]),
);

const flattened_public_inputs = flattenPublicInputsAsArray(witness_map);
const deflattened_public_inputs = deflattenPublicInputs(flattened_public_inputs, abi);

expect(deflattened_public_inputs).to.be.deep.eq(witness_map);
});
3 changes: 3 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3438,10 +3438,13 @@ __metadata:
"@noir-lang/types": "workspace:*"
"@types/node": ^20.6.2
"@types/prettier": ^3
chai: ^4.3.8
eslint: ^8.50.0
eslint-plugin-prettier: ^5.0.0
fflate: ^0.8.0
mocha: ^10.2.0
prettier: 3.0.3
ts-node: ^10.9.1
typescript: 5.1.5
languageName: unknown
linkType: soft
Expand Down
Loading