Skip to content

Commit 433b9eb

Browse files
authored
refactor: toFields()/fromFields(...) methods in more classes (AztecProtocol#4335)
Partially fixes AztecProtocol#4332 The goal of this PR was to progress on nuking yarn-project/acir-simulator/src/acvm/serialize.ts and move it to the individual classes to then be able to easily test it in the classes tests and improve readability. I didn't fully tackle the issue in this one because it was all getting too big.
1 parent e7db0da commit 433b9eb

30 files changed

+434
-340
lines changed

yarn-project/acir-simulator/src/acvm/deserialize.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ export function extractPrivateCircuitPublicInputs(
101101
const encryptedLogPreimagesLength = witnessReader.readField();
102102
const unencryptedLogPreimagesLength = witnessReader.readField();
103103

104-
const header = Header.fromFieldArray(witnessReader.readFieldArray(HEADER_LENGTH));
104+
const header = Header.fromFields(witnessReader.readFieldArray(HEADER_LENGTH));
105105

106106
const contractDeploymentData = new ContractDeploymentData(
107107
new Point(witnessReader.readField(), witnessReader.readField()),
@@ -176,7 +176,7 @@ export function extractPublicCircuitPublicInputs(partialWitness: ACVMWitness, ac
176176
const unencryptedLogsHash = witnessReader.readFieldArray(NUM_FIELDS_PER_SHA256);
177177
const unencryptedLogPreimagesLength = witnessReader.readField();
178178

179-
const header = Header.fromFieldArray(witnessReader.readFieldArray(HEADER_LENGTH));
179+
const header = Header.fromFields(witnessReader.readFieldArray(HEADER_LENGTH));
180180

181181
const proverAddress = AztecAddress.fromField(witnessReader.readField());
182182

yarn-project/acir-simulator/src/acvm/oracle/oracle.ts

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,7 @@ import { createDebugLogger } from '@aztec/foundation/log';
88

99
import { ACVMField } from '../acvm_types.js';
1010
import { frToNumber, fromACVMField } from '../deserialize.js';
11-
import {
12-
toACVMField,
13-
toACVMHeader,
14-
toAcvmCallPrivateStackItem,
15-
toAcvmEnqueuePublicFunctionResult,
16-
toAcvmL1ToL2MessageLoadOracleInputs,
17-
} from '../serialize.js';
11+
import { toACVMField, toAcvmEnqueuePublicFunctionResult } from '../serialize.js';
1812
import { acvmFieldMessageToString, oracleDebugCallToFormattedStr } from './debug.js';
1913
import { TypedOracle } from './typed_oracle.js';
2014

@@ -132,7 +126,7 @@ export class Oracle {
132126
if (!header) {
133127
throw new Error(`Block header not found for block ${parsedBlockNumber}.`);
134128
}
135-
return toACVMHeader(header);
129+
return header.toFields().map(toACVMField);
136130
}
137131

138132
async getAuthWitness([messageHash]: ACVMField[]): Promise<ACVMField[]> {
@@ -226,8 +220,8 @@ export class Oracle {
226220
}
227221

228222
async getL1ToL2Message([msgKey]: ACVMField[]): Promise<ACVMField[]> {
229-
const { ...message } = await this.typedOracle.getL1ToL2Message(fromACVMField(msgKey));
230-
return toAcvmL1ToL2MessageLoadOracleInputs(message);
223+
const message = await this.typedOracle.getL1ToL2Message(fromACVMField(msgKey));
224+
return message.toFields().map(toACVMField);
231225
}
232226

233227
async getPortalContractAddress([aztecAddress]: ACVMField[]): Promise<ACVMField> {
@@ -297,7 +291,7 @@ export class Oracle {
297291
fromACVMField(argsHash),
298292
frToNumber(fromACVMField(sideffectCounter)),
299293
);
300-
return toAcvmCallPrivateStackItem(callStackItem);
294+
return callStackItem.toFields().map(toACVMField);
301295
}
302296

303297
async callPublicFunction(

yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -48,23 +48,22 @@ export interface NoteData {
4848
index?: bigint;
4949
}
5050

51-
/**
52-
* The data for L1 to L2 Messages provided by other data sources.
53-
*/
54-
export interface MessageLoadOracleInputs {
55-
/**
56-
* An collapsed array of fields containing all of the l1 to l2 message components.
57-
* `l1ToL2Message.toFieldArray()` -\> [sender, chainId, recipient, version, content, secretHash, deadline, fee]
58-
*/
59-
message: Fr[];
60-
/**
61-
* The path in the merkle tree to the message.
62-
*/
63-
siblingPath: Fr[];
64-
/**
65-
* The index of the message commitment in the merkle tree.
66-
*/
67-
index: bigint;
51+
export class MessageLoadOracleInputs {
52+
constructor(
53+
/**
54+
* An collapsed array of fields containing all of the l1 to l2 message components.
55+
* `l1ToL2Message.toFieldArray()` -\> [sender, chainId, recipient, version, content, secretHash, deadline, fee]
56+
*/
57+
public message: Fr[],
58+
/** The index of the message commitment in the merkle tree. */
59+
public index: bigint,
60+
/** The path in the merkle tree to the message. */
61+
public siblingPath: Fr[],
62+
) {}
63+
64+
toFields(): Fr[] {
65+
return [...this.message, new Fr(this.index), ...this.siblingPath];
66+
}
6867
}
6968

7069
/**

yarn-project/acir-simulator/src/acvm/serialize.ts

Lines changed: 6 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,9 @@
1-
import {
2-
CallContext,
3-
ContractDeploymentData,
4-
FunctionData,
5-
GlobalVariables,
6-
Header,
7-
PrivateCallStackItem,
8-
PrivateCircuitPublicInputs,
9-
PublicCallRequest,
10-
} from '@aztec/circuits.js';
1+
import { PublicCallRequest } from '@aztec/circuits.js';
112
import { AztecAddress } from '@aztec/foundation/aztec-address';
123
import { EthAddress } from '@aztec/foundation/eth-address';
134
import { Fr } from '@aztec/foundation/fields';
145

156
import { ACVMField } from './acvm_types.js';
16-
import { MessageLoadOracleInputs } from './oracle/typed_oracle.js';
177

188
/**
199
* Adapts the buffer to the field size.
@@ -53,125 +43,6 @@ export function toACVMField(
5343
// Utilities to write TS classes to ACVM Field arrays
5444
// In the order that the ACVM expects them
5545

56-
/**
57-
* Converts a function data to ACVM fields.
58-
* @param functionData - The function data to convert.
59-
* @returns The ACVM fields.
60-
*/
61-
export function toACVMFunctionData(functionData: FunctionData): ACVMField[] {
62-
return [
63-
toACVMField(functionData.selector.toBuffer()),
64-
toACVMField(functionData.isInternal),
65-
toACVMField(functionData.isPrivate),
66-
toACVMField(functionData.isConstructor),
67-
];
68-
}
69-
70-
/**
71-
* Converts a call context to ACVM fields.
72-
* @param callContext - The call context to convert.
73-
* @returns The ACVM fields.
74-
*/
75-
export function toACVMCallContext(callContext: CallContext): ACVMField[] {
76-
return [
77-
toACVMField(callContext.msgSender),
78-
toACVMField(callContext.storageContractAddress),
79-
toACVMField(callContext.portalContractAddress),
80-
toACVMField(callContext.functionSelector.toField()),
81-
toACVMField(callContext.isDelegateCall),
82-
toACVMField(callContext.isStaticCall),
83-
toACVMField(callContext.isContractDeployment),
84-
toACVMField(callContext.startSideEffectCounter),
85-
];
86-
}
87-
88-
/**
89-
* Converts a contract deployment data to ACVM fields.
90-
* @param contractDeploymentData - The contract deployment data to convert.
91-
* @returns The ACVM fields.
92-
*/
93-
export function toACVMContractDeploymentData(contractDeploymentData: ContractDeploymentData): ACVMField[] {
94-
return [
95-
toACVMField(contractDeploymentData.publicKey.x),
96-
toACVMField(contractDeploymentData.publicKey.y),
97-
toACVMField(contractDeploymentData.initializationHash),
98-
toACVMField(contractDeploymentData.contractClassId),
99-
toACVMField(contractDeploymentData.contractAddressSalt),
100-
toACVMField(contractDeploymentData.portalContractAddress),
101-
];
102-
}
103-
104-
/**
105-
* Converts a block header into ACVM fields.
106-
* @param header - The block header object to convert.
107-
* @returns The ACVM fields.
108-
*/
109-
export function toACVMHeader(header: Header): ACVMField[] {
110-
return header.toFieldArray().map(toACVMField);
111-
}
112-
113-
/**
114-
* Converts global variables into ACVM fields
115-
* @param globalVariables - The global variables object to convert.
116-
* @returns The ACVM fields
117-
*/
118-
export function toACVMGlobalVariables(globalVariables: GlobalVariables): ACVMField[] {
119-
return [
120-
toACVMField(globalVariables.chainId),
121-
toACVMField(globalVariables.version),
122-
toACVMField(globalVariables.blockNumber),
123-
toACVMField(globalVariables.timestamp),
124-
];
125-
}
126-
127-
/**
128-
* Converts the public inputs structure to ACVM fields.
129-
* @param publicInputs - The public inputs to convert.
130-
* @returns The ACVM fields.
131-
*/
132-
export function toACVMPublicInputs(publicInputs: PrivateCircuitPublicInputs): ACVMField[] {
133-
return [
134-
...toACVMCallContext(publicInputs.callContext),
135-
toACVMField(publicInputs.argsHash),
136-
137-
...publicInputs.returnValues.map(toACVMField),
138-
...publicInputs.readRequests.flatMap(x => x.toFields()).map(toACVMField),
139-
...publicInputs.nullifierKeyValidationRequests.flatMap(x => x.toFields()).map(toACVMField),
140-
...publicInputs.newCommitments.flatMap(x => x.toFields()).map(toACVMField),
141-
...publicInputs.newNullifiers.flatMap(x => x.toFields()).map(toACVMField),
142-
...publicInputs.privateCallStackHashes.map(toACVMField),
143-
...publicInputs.publicCallStackHashes.map(toACVMField),
144-
...publicInputs.newL2ToL1Msgs.map(toACVMField),
145-
toACVMField(publicInputs.endSideEffectCounter),
146-
...publicInputs.encryptedLogsHash.map(toACVMField),
147-
...publicInputs.unencryptedLogsHash.map(toACVMField),
148-
149-
toACVMField(publicInputs.encryptedLogPreimagesLength),
150-
toACVMField(publicInputs.unencryptedLogPreimagesLength),
151-
152-
...toACVMHeader(publicInputs.historicalHeader),
153-
154-
...toACVMContractDeploymentData(publicInputs.contractDeploymentData),
155-
156-
toACVMField(publicInputs.chainId),
157-
toACVMField(publicInputs.version),
158-
];
159-
}
160-
161-
/**
162-
* Converts a private call stack item to ACVM fields.
163-
* @param item - The private call stack item to convert.
164-
* @returns The ACVM fields.
165-
*/
166-
export function toAcvmCallPrivateStackItem(item: PrivateCallStackItem): ACVMField[] {
167-
return [
168-
toACVMField(item.contractAddress),
169-
...toACVMFunctionData(item.functionData),
170-
...toACVMPublicInputs(item.publicInputs),
171-
toACVMField(item.isExecutionRequest),
172-
];
173-
}
174-
17546
/**
17647
* Converts a public call stack item with the request for executing a public function to
17748
* a set of ACVM fields accepted by the enqueue_public_function_call_oracle Aztec.nr function.
@@ -182,24 +53,11 @@ export function toAcvmCallPrivateStackItem(item: PrivateCallStackItem): ACVMFiel
18253
*/
18354
export function toAcvmEnqueuePublicFunctionResult(item: PublicCallRequest): ACVMField[] {
18455
return [
185-
toACVMField(item.contractAddress),
186-
...toACVMFunctionData(item.functionData),
187-
...toACVMCallContext(item.callContext),
188-
toACVMField(item.getArgsHash()),
189-
];
190-
}
191-
192-
/**
193-
* Converts the result of loading messages to ACVM fields.
194-
* @param messageLoadOracleInputs - The result of loading messages to convert.
195-
* @returns The Message Oracle Fields.
196-
*/
197-
export function toAcvmL1ToL2MessageLoadOracleInputs(messageLoadOracleInputs: MessageLoadOracleInputs): ACVMField[] {
198-
return [
199-
...messageLoadOracleInputs.message.map(f => toACVMField(f)),
200-
toACVMField(messageLoadOracleInputs.index),
201-
...messageLoadOracleInputs.siblingPath.map(f => toACVMField(f)),
202-
];
56+
item.contractAddress.toField(),
57+
...item.functionData.toFields(),
58+
...item.callContext.toFields(),
59+
item.getArgsHash(),
60+
].map(toACVMField);
20361
}
20462

20563
/**

yarn-project/acir-simulator/src/client/client_execution_context.ts

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,7 @@ import { AztecAddress } from '@aztec/foundation/aztec-address';
1717
import { Fr, Point } from '@aztec/foundation/fields';
1818
import { createDebugLogger } from '@aztec/foundation/log';
1919

20-
import {
21-
NoteData,
22-
toACVMCallContext,
23-
toACVMContractDeploymentData,
24-
toACVMHeader,
25-
toACVMWitness,
26-
} from '../acvm/index.js';
20+
import { NoteData, toACVMWitness } from '../acvm/index.js';
2721
import { PackedArgsCache } from '../common/packed_args_cache.js';
2822
import { DBOracle } from './db_oracle.js';
2923
import { ExecutionNoteCache } from './execution_note_cache.js';
@@ -96,9 +90,9 @@ export class ClientExecutionContext extends ViewDataOracle {
9690
}
9791

9892
const fields = [
99-
...toACVMCallContext(this.callContext),
100-
...toACVMHeader(this.historicalHeader),
101-
...toACVMContractDeploymentData(contractDeploymentData),
93+
...this.callContext.toFields(),
94+
...this.historicalHeader.toFields(),
95+
...contractDeploymentData.toFields(),
10296

10397
this.txContext.chainId,
10498
this.txContext.version,

yarn-project/acir-simulator/src/client/private_execution.test.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ import { jest } from '@jest/globals';
5656
import { MockProxy, mock } from 'jest-mock-extended';
5757
import { getFunctionSelector } from 'viem';
5858

59-
import { KeyPair } from '../acvm/index.js';
59+
import { KeyPair, MessageLoadOracleInputs } from '../acvm/index.js';
6060
import { buildL1ToL2Message } from '../test/utils.js';
6161
import { computeSlotForMapping } from '../utils.js';
6262
import { DBOracle } from './db_oracle.js';
@@ -544,11 +544,13 @@ describe('Private Execution test suite', () => {
544544
const mockOracles = async () => {
545545
const tree = await insertLeaves([messageKey ?? preimage.hash()], 'l1ToL2Messages');
546546
oracle.getL1ToL2Message.mockImplementation(async () => {
547-
return Promise.resolve({
548-
message: preimage.toFieldArray(),
549-
index: 0n,
550-
siblingPath: (await tree.getSiblingPath(0n, false)).toFieldArray(),
551-
});
547+
return Promise.resolve(
548+
new MessageLoadOracleInputs(
549+
preimage.toFieldArray(),
550+
0n,
551+
(await tree.getSiblingPath(0n, false)).toFieldArray(),
552+
),
553+
);
552554
});
553555
};
554556

yarn-project/acir-simulator/src/public/index.test.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { MockProxy, mock } from 'jest-mock-extended';
2121
import { type MemDown, default as memdown } from 'memdown';
2222
import { getFunctionSelector } from 'viem';
2323

24+
import { MessageLoadOracleInputs } from '../index.js';
2425
import { buildL1ToL2Message } from '../test/utils.js';
2526
import { computeSlotForMapping } from '../utils.js';
2627
import { CommitmentsDB, PublicContractsDB, PublicStateDB } from './db.js';
@@ -459,12 +460,8 @@ describe('ACIR public execution simulator', () => {
459460
for (const sibling of siblingPath) {
460461
root = Fr.fromBuffer(pedersenHash([root.toBuffer(), sibling.toBuffer()]));
461462
}
462-
commitmentsDb.getL1ToL2Message.mockImplementation(async () => {
463-
return await Promise.resolve({
464-
message: preimage.toFieldArray(),
465-
index: 0n,
466-
siblingPath,
467-
});
463+
commitmentsDb.getL1ToL2Message.mockImplementation(() => {
464+
return Promise.resolve(new MessageLoadOracleInputs(preimage.toFieldArray(), 0n, siblingPath));
468465
});
469466

470467
return new AppendOnlyTreeSnapshot(

yarn-project/acir-simulator/src/public/public_execution_context.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { EthAddress } from '@aztec/foundation/eth-address';
55
import { Fr } from '@aztec/foundation/fields';
66
import { createDebugLogger } from '@aztec/foundation/log';
77

8-
import { TypedOracle, toACVMCallContext, toACVMGlobalVariables, toACVMHeader, toACVMWitness } from '../acvm/index.js';
8+
import { TypedOracle, toACVMWitness } from '../acvm/index.js';
99
import { PackedArgsCache, SideEffectCounter } from '../common/index.js';
1010
import { CommitmentsDB, PublicContractsDB, PublicStateDB } from './db.js';
1111
import { PublicExecution, PublicExecutionResult } from './execution.js';
@@ -49,13 +49,7 @@ export class PublicExecutionContext extends TypedOracle {
4949
*/
5050
public getInitialWitness(witnessStartIndex = 0) {
5151
const { callContext, args } = this.execution;
52-
const fields = [
53-
...toACVMCallContext(callContext),
54-
...toACVMHeader(this.header),
55-
...toACVMGlobalVariables(this.globalVariables),
56-
57-
...args,
58-
];
52+
const fields = [...callContext.toFields(), ...this.header.toFields(), ...this.globalVariables.toFields(), ...args];
5953

6054
return toACVMWitness(witnessStartIndex, fields);
6155
}

yarn-project/circuits.js/src/abis/abis.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ function computePrivateInputsHash(input: PrivateCircuitPublicInputs) {
397397
...input.unencryptedLogsHash.map(fr => fr.toBuffer()),
398398
input.encryptedLogPreimagesLength.toBuffer(),
399399
input.unencryptedLogPreimagesLength.toBuffer(),
400-
...(input.historicalHeader.toFieldArray().map(fr => fr.toBuffer()) as Buffer[]),
400+
...(input.historicalHeader.toFields().map(fr => fr.toBuffer()) as Buffer[]),
401401
computeContractDeploymentDataHash(input.contractDeploymentData).toBuffer(),
402402
input.chainId.toBuffer(),
403403
input.version.toBuffer(),
@@ -463,7 +463,7 @@ export function computePublicInputsHash(input: PublicCircuitPublicInputs) {
463463
...input.newL2ToL1Msgs.map(fr => fr.toBuffer()),
464464
...input.unencryptedLogsHash.map(fr => fr.toBuffer()),
465465
input.unencryptedLogPreimagesLength.toBuffer(),
466-
...input.historicalHeader.toFieldArray().map(fr => fr.toBuffer()),
466+
...input.historicalHeader.toFields().map(fr => fr.toBuffer()),
467467
input.proverAddress.toBuffer(),
468468
];
469469
if (toHash.length != PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH) {

0 commit comments

Comments
 (0)