Skip to content

Commit

Permalink
refactor: PublicCircuitPublicInputs cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
benesjan committed Feb 1, 2024
1 parent 4edcc65 commit 7950142
Show file tree
Hide file tree
Showing 6 changed files with 206 additions and 129 deletions.
21 changes: 21 additions & 0 deletions yarn-project/circuits.js/src/structs/contract_storage_read.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { makeContractStorageRead } from '../tests/factories.js';
import { ContractStorageRead } from './contract_storage_read.js';

describe('ContractStorageRead', () => {
it('serializes to buffer and deserializes it back', () => {
const randomInt = Math.floor(Math.random() * 1000);
const expected = makeContractStorageRead(randomInt);
const buffer = expected.toBuffer();
const res = ContractStorageRead.fromBuffer(buffer);
expect(res).toEqual(expected);
});

it('serializes to field array and deserializes it back', () => {
const randomInt = Math.floor(Math.random() * 1000);
const expected = makeContractStorageRead(randomInt);

const fieldArray = expected.toFields();
const res = ContractStorageRead.fromFields(fieldArray);
expect(res).toEqual(expected);
});
});
77 changes: 77 additions & 0 deletions yarn-project/circuits.js/src/structs/contract_storage_read.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { Fr } from '@aztec/foundation/fields';
import { BufferReader, FieldReader, serializeToBuffer } from '@aztec/foundation/serialize';

/**
* Contract storage read operation on a specific contract.
*
* Note: Similar to `PublicDataRead` but it's from the POV of contract storage so we are not working with public data
* tree leaf index but storage slot index.
*/
export class ContractStorageRead {
constructor(
/**
* Storage slot we are reading from.
*/
public readonly storageSlot: Fr,
/**
* Value read from the storage slot.
*/
public readonly currentValue: Fr,
/**
* Optional side effect counter tracking position of this event in tx execution.
* Note: Not serialized
*/
public readonly sideEffectCounter?: number,
) {}

static from(args: {
/**
* Storage slot we are reading from.
*/
storageSlot: Fr;
/**
* Value read from the storage slot.
*/
currentValue: Fr;
/**
* Optional side effect counter tracking position of this event in tx execution.
*/
sideEffectCounter?: number;
}) {
return new ContractStorageRead(args.storageSlot, args.currentValue, args.sideEffectCounter);
}

toBuffer() {
return serializeToBuffer(this.storageSlot, this.currentValue);
}

static fromBuffer(buffer: Buffer | BufferReader) {
const reader = BufferReader.asReader(buffer);
return new ContractStorageRead(Fr.fromBuffer(reader), Fr.fromBuffer(reader));
}

static empty() {
return new ContractStorageRead(Fr.ZERO, Fr.ZERO);
}

isEmpty() {
return this.storageSlot.isZero() && this.currentValue.isZero();
}

toFriendlyJSON() {
return `Slot=${this.storageSlot.toFriendlyJSON()}: ${this.currentValue.toFriendlyJSON()}`;
}

toFields(): Fr[] {
return [this.storageSlot, this.currentValue];
}

static fromFields(fields: Fr[] | FieldReader): ContractStorageRead {
const reader = FieldReader.asReader(fields);

const storageSlot = reader.readField();
const currentValue = reader.readField();

return new ContractStorageRead(storageSlot, currentValue);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { makeContractStorageUpdateRequest } from '../tests/factories.js';
import { ContractStorageUpdateRequest } from './contract_storage_update_request.js';

describe('ContractStorageUpdateRequest', () => {
it('serializes to buffer and deserializes it back', () => {
const randomInt = Math.floor(Math.random() * 1000);
const expected = makeContractStorageUpdateRequest(randomInt);
const buffer = expected.toBuffer();
const res = ContractStorageUpdateRequest.fromBuffer(buffer);
expect(res).toEqual(expected);
});

it('serializes to field array and deserializes it back', () => {
const randomInt = Math.floor(Math.random() * 1000);
const expected = makeContractStorageUpdateRequest(randomInt);

const fieldArray = expected.toFields();
const res = ContractStorageUpdateRequest.fromFields(fieldArray);
expect(res).toEqual(expected);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { Fr } from '@aztec/foundation/fields';
import { BufferReader, FieldReader, serializeToBuffer } from '@aztec/foundation/serialize';
import { FieldsOf } from '@aztec/foundation/types';

/**
* Contract storage update request for a slot on a specific contract.
*
* Note: Similar to `PublicDataUpdateRequest` but it's from the POV of contract storage so we are not working with
* public data tree leaf index but storage slot index.
*/
export class ContractStorageUpdateRequest {
constructor(
/**
* Storage slot we are updating.
*/
public readonly storageSlot: Fr,
/**
* Old value of the storage slot.
*/
public readonly oldValue: Fr,
/**
* New value of the storage slot.
*/
public readonly newValue: Fr,
/**
* Optional side effect counter tracking position of this event in tx execution.
*/
public readonly sideEffectCounter?: number,
) {}

toBuffer() {
return serializeToBuffer(this.storageSlot, this.oldValue, this.newValue);
}

static fromBuffer(buffer: Buffer | BufferReader) {
const reader = BufferReader.asReader(buffer);
return new ContractStorageUpdateRequest(Fr.fromBuffer(reader), Fr.fromBuffer(reader), Fr.fromBuffer(reader));
}

/**
* Create PublicCallRequest from a fields dictionary.
* @param fields - The dictionary.
* @returns A PublicCallRequest object.
*/
static from(fields: FieldsOf<ContractStorageUpdateRequest>): ContractStorageUpdateRequest {
return new ContractStorageUpdateRequest(...ContractStorageUpdateRequest.getFields(fields));
}

/**
* Serialize into a field array. Low-level utility.
* @param fields - Object with fields.
* @returns The array.
*/
static getFields(fields: FieldsOf<ContractStorageUpdateRequest>) {
return [fields.storageSlot, fields.oldValue, fields.newValue, fields.sideEffectCounter] as const;
}

static empty() {
return new ContractStorageUpdateRequest(Fr.ZERO, Fr.ZERO, Fr.ZERO);
}

isEmpty() {
return this.storageSlot.isZero() && this.oldValue.isZero() && this.newValue.isZero();
}

toFriendlyJSON() {
return `Slot=${this.storageSlot.toFriendlyJSON()}: ${this.oldValue.toFriendlyJSON()} => ${this.newValue.toFriendlyJSON()}`;
}

toFields(): Fr[] {
return [this.storageSlot, this.oldValue, this.newValue];
}

static fromFields(fields: Fr[] | FieldReader): ContractStorageUpdateRequest {
const reader = FieldReader.asReader(fields);

const storageSlot = reader.readField();
const oldValue = reader.readField();
const newValue = reader.readField();

return new ContractStorageUpdateRequest(storageSlot, oldValue, newValue);
}
}
2 changes: 2 additions & 0 deletions yarn-project/circuits.js/src/structs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ export * from './call_request.js';
export * from './call_stack_item.js';
export * from './complete_address.js';
export * from './contract_deployment_data.js';
export * from './contract_storage_read.js';
export * from './contract_storage_update_request.js';
export * from './function_data.js';
export * from './function_leaf_preimage.js';
export * from './global_variables.js';
Expand Down
131 changes: 2 additions & 129 deletions yarn-project/circuits.js/src/structs/public_circuit_public_inputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { makeTuple } from '@aztec/foundation/array';
import { AztecAddress } from '@aztec/foundation/aztec-address';
import { isArrayEmpty } from '@aztec/foundation/collection';
import { Fr } from '@aztec/foundation/fields';
import { BufferReader, Tuple, serializeToBuffer } from '@aztec/foundation/serialize';
import { Tuple, serializeToBuffer } from '@aztec/foundation/serialize';
import { FieldsOf } from '@aztec/foundation/types';

import {
Expand All @@ -15,134 +15,7 @@ import {
RETURN_VALUES_LENGTH,
} from '../constants.gen.js';
import { CallContext } from './call_context.js';
import { Header, SideEffect, SideEffectLinkedToNoteHash } from './index.js';

/**
* Contract storage read operation on a specific contract.
*
* Note: Similar to `PublicDataRead` but it's from the POV of contract storage so we are not working with public data
* tree leaf index but storage slot index.
*/
export class ContractStorageRead {
constructor(
/**
* Storage slot we are reading from.
*/
public readonly storageSlot: Fr,
/**
* Value read from the storage slot.
*/
public readonly currentValue: Fr,
/**
* Optional side effect counter tracking position of this event in tx execution.
*/
public readonly sideEffectCounter?: number,
) {}

static from(args: {
/**
* Storage slot we are reading from.
*/
storageSlot: Fr;
/**
* Value read from the storage slot.
*/
currentValue: Fr;
/**
* Optional side effect counter tracking position of this event in tx execution.
*/
sideEffectCounter?: number;
}) {
return new ContractStorageRead(args.storageSlot, args.currentValue, args.sideEffectCounter);
}

toBuffer() {
return serializeToBuffer(this.storageSlot, this.currentValue);
}

static fromBuffer(buffer: Buffer | BufferReader) {
const reader = BufferReader.asReader(buffer);
return new ContractStorageRead(Fr.fromBuffer(reader), Fr.fromBuffer(reader));
}

static empty() {
return new ContractStorageRead(Fr.ZERO, Fr.ZERO);
}

isEmpty() {
return this.storageSlot.isZero() && this.currentValue.isZero();
}

toFriendlyJSON() {
return `Slot=${this.storageSlot.toFriendlyJSON()}: ${this.currentValue.toFriendlyJSON()}`;
}
}

/**
* Contract storage update request for a slot on a specific contract.
*
* Note: Similar to `PublicDataUpdateRequest` but it's from the POV of contract storage so we are not working with
* public data tree leaf index but storage slot index.
*/
export class ContractStorageUpdateRequest {
constructor(
/**
* Storage slot we are updating.
*/
public readonly storageSlot: Fr,
/**
* Old value of the storage slot.
*/
public readonly oldValue: Fr,
/**
* New value of the storage slot.
*/
public readonly newValue: Fr,
/**
* Optional side effect counter tracking position of this event in tx execution.
*/
public readonly sideEffectCounter?: number,
) {}

toBuffer() {
return serializeToBuffer(this.storageSlot, this.oldValue, this.newValue);
}

static fromBuffer(buffer: Buffer | BufferReader) {
const reader = BufferReader.asReader(buffer);
return new ContractStorageUpdateRequest(Fr.fromBuffer(reader), Fr.fromBuffer(reader), Fr.fromBuffer(reader));
}

/**
* Create PublicCallRequest from a fields dictionary.
* @param fields - The dictionary.
* @returns A PublicCallRequest object.
*/
static from(fields: FieldsOf<ContractStorageUpdateRequest>): ContractStorageUpdateRequest {
return new ContractStorageUpdateRequest(...ContractStorageUpdateRequest.getFields(fields));
}

/**
* Serialize into a field array. Low-level utility.
* @param fields - Object with fields.
* @returns The array.
*/
static getFields(fields: FieldsOf<ContractStorageUpdateRequest>) {
return [fields.storageSlot, fields.oldValue, fields.newValue, fields.sideEffectCounter] as const;
}

static empty() {
return new ContractStorageUpdateRequest(Fr.ZERO, Fr.ZERO, Fr.ZERO);
}

isEmpty() {
return this.storageSlot.isZero() && this.oldValue.isZero() && this.newValue.isZero();
}

toFriendlyJSON() {
return `Slot=${this.storageSlot.toFriendlyJSON()}: ${this.oldValue.toFriendlyJSON()} => ${this.newValue.toFriendlyJSON()}`;
}
}
import { ContractStorageRead, ContractStorageUpdateRequest, Header, SideEffect, SideEffectLinkedToNoteHash } from './index.js';

/**
* Public inputs to a public circuit.
Expand Down

0 comments on commit 7950142

Please sign in to comment.