Skip to content

Commit 25a7ea7

Browse files
authored
feat!: Unencrypted logs are not strings (AztecProtocol#4392)
The private execution oracle was assuming unencrypted log payloads were strings, where each character was encoded as a field. This means that emitting a field array did not work, since all bytes but the least significant one for each field were thrown out. Given we are not emitting strings from anywhere across our sample contracts, this commit changes the oracle so it does not throw away the fields contents, and instead pushes everything into the log payload.
1 parent 6895f52 commit 25a7ea7

File tree

3 files changed

+28
-1
lines changed

3 files changed

+28
-1
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ export class Oracle {
258258
}
259259

260260
emitUnencryptedLog([contractAddress]: ACVMField[], [eventSelector]: ACVMField[], message: ACVMField[]): ACVMField {
261-
const logPayload = Buffer.concat(message.map(charBuffer => Fr.fromString(charBuffer).toBuffer().subarray(-1)));
261+
const logPayload = Buffer.concat(message.map(fromACVMField).map(f => f.toBuffer()));
262262
const log = new UnencryptedL2Log(
263263
AztecAddress.fromString(contractAddress),
264264
EventSelector.fromField(fromACVMField(eventSelector)),

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import {
3535
} from '@aztec/foundation/abi';
3636
import { asyncMap } from '@aztec/foundation/async-map';
3737
import { AztecAddress } from '@aztec/foundation/aztec-address';
38+
import { times } from '@aztec/foundation/collection';
3839
import { pedersenHash } from '@aztec/foundation/crypto';
3940
import { EthAddress } from '@aztec/foundation/eth-address';
4041
import { Fr, GrumpkinScalar } from '@aztec/foundation/fields';
@@ -60,6 +61,7 @@ import { KeyPair, MessageLoadOracleInputs } from '../acvm/index.js';
6061
import { buildL1ToL2Message } from '../test/utils.js';
6162
import { computeSlotForMapping } from '../utils.js';
6263
import { DBOracle } from './db_oracle.js';
64+
import { collectUnencryptedLogs } from './execution_result.js';
6365
import { AcirSimulator } from './simulator.js';
6466

6567
jest.setTimeout(60_000);
@@ -232,6 +234,26 @@ describe('Private Execution test suite', () => {
232234
expect(sideEffectArrayToValueArray(result.callStackItem.publicInputs.newCommitments)).toEqual(emptyCommitments);
233235
expect(result.callStackItem.publicInputs.contractDeploymentData).toEqual(contractDeploymentData);
234236
});
237+
238+
it('emits a field as an unencrypted log', async () => {
239+
const artifact = getFunctionArtifact(TestContractArtifact, 'emit_msg_sender');
240+
const result = await runSimulator({ artifact, msgSender: owner });
241+
const [functionLogs] = collectUnencryptedLogs(result);
242+
expect(functionLogs.logs).toHaveLength(1);
243+
// Test that the log payload (ie ignoring address, selector, and header) matches what we emitted
244+
expect(functionLogs.logs[0].subarray(-32).toString('hex')).toEqual(owner.toBuffer().toString('hex'));
245+
});
246+
247+
it('emits a field array as an unencrypted log', async () => {
248+
const artifact = getFunctionArtifact(TestContractArtifact, 'emit_array_as_unencrypted_log');
249+
const args = [times(5, () => Fr.random())];
250+
const result = await runSimulator({ artifact, msgSender: owner, args });
251+
const [functionLogs] = collectUnencryptedLogs(result);
252+
expect(functionLogs.logs).toHaveLength(1);
253+
// Test that the log payload (ie ignoring address, selector, and header) matches what we emitted
254+
const expected = Buffer.concat(args[0].map(arg => arg.toBuffer())).toString('hex');
255+
expect(functionLogs.logs[0].subarray(-32 * 5).toString('hex')).toEqual(expected);
256+
});
235257
});
236258

237259
describe('stateful test contract', () => {

yarn-project/noir-contracts/contracts/test_contract/src/main.nr

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,11 @@ contract Test {
233233
emit_unencrypted_log_from_private(&mut context, context.msg_sender());
234234
}
235235

236+
#[aztec(private)]
237+
fn emit_array_as_unencrypted_log(fields: [Field; 5]) {
238+
emit_unencrypted_log_from_private(&mut context, fields);
239+
}
240+
236241
// docs:start:is-time-equal
237242
#[aztec(public)]
238243
fn is_time_equal(time: Field) -> Field {

0 commit comments

Comments
 (0)