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
22 changes: 19 additions & 3 deletions yarn-project/circuits.js/src/contract/artifact_hash.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { type ContractArtifact } from '@aztec/foundation/abi';
import { loadContractArtifact } from '@aztec/types/abi';
import type { NoirCompiledContract } from '@aztec/types/noir';

import { getTestContractArtifact } from '../tests/fixtures.js';
import { readFileSync } from 'fs';

import { getPathToFixture, getTestContractArtifact } from '../tests/fixtures.js';
import { computeArtifactHash } from './artifact_hash.js';

describe('ArtifactHash', () => {
Expand All @@ -17,7 +21,7 @@ describe('ArtifactHash', () => {
notes: {},
};
expect(computeArtifactHash(emptyArtifact).toString()).toMatchInlineSnapshot(
`"0x0c6fd9b48570721c5d36f978d084d77cacbfd2814f1344985f40e62bea6e61be"`,
`"0x0dea64e7fa0688017f77bcb7075485485afb4a5f1f8508483398869439f82fdf"`,
);
});

Expand All @@ -26,8 +30,20 @@ describe('ArtifactHash', () => {

for (let i = 0; i < 1000; i++) {
expect(computeArtifactHash(testArtifact).toString()).toMatchInlineSnapshot(
`"0x11ba97d2d4de6335cc86d271d3c4a6237840cf630eaa442cf75d1666ff475f61"`,
`"0x237feccc8e34a39c0e5133c8653fc278b39275bfa3f7459e4aba07d53b752c19"`,
);
}
});

it('calculates the test contract artifact hash', () => {
const path = getPathToFixture('Test.test.json');
const content = JSON.parse(readFileSync(path).toString()) as NoirCompiledContract;
content.outputs.structs.functions.reverse();

const testArtifact = loadContractArtifact(content);

expect(computeArtifactHash(testArtifact).toString()).toMatchInlineSnapshot(
`"0x237feccc8e34a39c0e5133c8653fc278b39275bfa3f7459e4aba07d53b752c19"`,
);
});
});
6 changes: 1 addition & 5 deletions yarn-project/circuits.js/src/contract/artifact_hash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,7 @@ export function computeArtifactHashPreimage(artifact: ContractArtifact) {
}

export function computeArtifactMetadataHash(artifact: ContractArtifact) {
// TODO: #6021 We need to make sure the artifact is deterministic from any specific compiler run. This relates to selectors not being sorted and being
// apparently random in the order they appear after compiled w/ nargo. We can try to sort this upon loading an artifact.
// TODO: #6021: Should we use the sorted event selectors instead? They'd need to be unique for that.
Comment on lines -62 to -64

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should these issues not be closed?

// Response - The output selectors need to be sorted, because if not noir makes no guarantees on the order of outputs for some reason
return sha256Fr(Buffer.from(JSON.stringify({ name: artifact.name }), 'utf-8'));
return sha256Fr(Buffer.from(JSON.stringify({ name: artifact.name, outputs: artifact.outputs }), 'utf-8'));
}

export function computeArtifactFunctionTreeRoot(artifact: ContractArtifact, fnType: FunctionType) {
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/circuits.js/src/tests/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,6 @@ export function getSampleUnconstrainedFunctionBroadcastedEventPayload(): Buffer
return Buffer.from(readFileSync(path).toString(), 'hex');
}

function getPathToFixture(name: string) {
export function getPathToFixture(name: string) {
return resolve(dirname(fileURLToPath(import.meta.url)), `../../fixtures/${name}`);
}
13 changes: 12 additions & 1 deletion yarn-project/foundation/src/abi/abi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,18 @@ export const ContractArtifactSchema: ZodFor<ContractArtifact> = z.object({
aztecNrVersion: z.string().optional(),
functions: z.array(FunctionArtifactSchema),
outputs: z.object({
structs: z.record(z.array(AbiTypeSchema)),
structs: z.record(z.array(AbiTypeSchema)).transform(structs => {
for (const [key, value] of Object.entries(structs)) {
// We are manually ordering events and functions in the abi by path.
// The path ordering is arbitrary, and only needed to ensure deterministic order.
Comment thread
sklppy88 marked this conversation as resolved.
// These are the only arrays in the artifact with arbitrary order, and hence the only ones
// we need to sort.
if (key === 'events' || key === 'functions') {
structs[key] = (value as StructType[]).sort((a, b) => (a.path > b.path ? -1 : 1));
}
}
return structs;
}),
globals: z.record(z.array(AbiValueSchema)),
}),
storageLayout: z.record(z.object({ slot: schemas.Fr })),
Expand Down