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

refactor: Use serialize functions in getInitialWitness #2713

Merged
merged 1 commit into from
Oct 5, 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
21 changes: 20 additions & 1 deletion yarn-project/acir-simulator/src/acvm/serialize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
CallContext,
ContractDeploymentData,
FunctionData,
GlobalVariables,
HistoricBlockData,
PrivateCallStackItem,
PrivateCircuitPublicInputs,
Expand Down Expand Up @@ -33,12 +34,16 @@ function adaptBufferSize(originalBuf: Buffer) {
* @param value - The value to convert.
* @returns The ACVM field.
*/
export function toACVMField(value: AztecAddress | EthAddress | Fr | Buffer | boolean | number | bigint): ACVMField {
export function toACVMField(
value: AztecAddress | EthAddress | Fr | Buffer | boolean | number | bigint | ACVMField,
): ACVMField {
let buffer;
if (Buffer.isBuffer(value)) {
buffer = value;
} else if (typeof value === 'boolean' || typeof value === 'number' || typeof value === 'bigint') {
buffer = new Fr(value).toBuffer();
} else if (typeof value === 'string') {
buffer = Fr.fromString(value).toBuffer();
Comment on lines +37 to +46
Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe we can add a type guard for isACVMField that checks that it's a hex value of the correct length and if is ACVMField just short circuit the conversion to/from buffer? It'd remove any performance impact of this refactor :D

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The size and such should already be handled by the fromString that was why I just ended up using that 👀. The frombuffer is reading 32 bytes, so if it is of wrong size should break there.

  /**
   * Create a Fr instance from a hex-encoded string.
   * The input 'address' can be either prefixed with '0x' or not, and should have exactly 64 hex characters.
   * Throws an error if the input length is invalid or the address value is out of range.
   *
   * @param address - The hex-encoded string representing the field element.
   * @returns A Fr instance.
   */
  static fromString(address: string) {
    return Fr.fromBuffer(Buffer.from(address.replace(/^0x/i, ''), 'hex'));
  }

Copy link
Collaborator

@sirasistant sirasistant Oct 5, 2023

Choose a reason for hiding this comment

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

Oh yeah I wasn't meaning as validation, It's because, suppose that the toACVMField receives an ACVMField (where it could just return the parameter without any operation)
Then we now would be doing:
Fr.fromString() => internally does Fr.fromBuffer() and Buffer.from(string)
Then fr.toBuffer()
Then buffer.toString('hex')

so that's many conversions to/from buffer when if it's sure about the type it can just return the parameter without doing anything. So with a type guard, you could:

function isACVMField(value: any): value is ACVMField {
  ... // Check here if hex string and a hex regex with the ACVMField length for example
}

// Then in toACVMField
...
if (isACVMField(value)) {
    return value
}
... The rest of the function

But maybe it's not that efficient if we need to check in runtime if it's an ACVMField with a regex ): Maybe I'm overcomplicating myself. The truly zero runtime cost would be to convert ACVMField to a branded string but that's more painful

} else {
buffer = value.toBuffer();
}
Expand Down Expand Up @@ -112,6 +117,20 @@ export function toACVMHistoricBlockData(historicBlockData: HistoricBlockData): A
];
}

/**
* Converts global variables into ACVM fields
* @param globalVariables - The global variables object to convert.
* @returns The ACVM fields
*/
export function toACVMGlobalVariables(globalVariables: GlobalVariables): ACVMField[] {
return [
toACVMField(globalVariables.chainId),
toACVMField(globalVariables.version),
toACVMField(globalVariables.blockNumber),
toACVMField(globalVariables.timestamp),
];
}

/**
* Converts the public inputs structure to ACVM fields.
* @param publicInputs - The public inputs to convert.
Expand Down
27 changes: 10 additions & 17 deletions yarn-project/acir-simulator/src/client/client_execution_context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,13 @@ import { Fr, Point } from '@aztec/foundation/fields';
import { createDebugLogger } from '@aztec/foundation/log';
import { AuthWitness, FunctionL2Logs, NotePreimage, NoteSpendingInfo, UnencryptedL2Log } from '@aztec/types';

import { NoteData, toACVMWitness } from '../acvm/index.js';
import {
NoteData,
toACVMCallContext,
toACVMContractDeploymentData,
toACVMHistoricBlockData,
toACVMWitness,
} from '../acvm/index.js';
import { SideEffectCounter } from '../common/index.js';
import { PackedArgsCache } from '../common/packed_args_cache.js';
import { DBOracle } from './db_oracle.js';
Expand Down Expand Up @@ -83,22 +89,9 @@ export class ClientExecutionContext extends ViewDataOracle {
const contractDeploymentData = this.txContext.contractDeploymentData;

const fields = [
this.callContext.msgSender,
this.callContext.storageContractAddress,
this.callContext.portalContractAddress,
this.callContext.functionSelector.toField(),
this.callContext.isDelegateCall,
this.callContext.isStaticCall,
this.callContext.isContractDeployment,

...this.historicBlockData.toArray(),

contractDeploymentData.deployerPublicKey.x,
contractDeploymentData.deployerPublicKey.y,
contractDeploymentData.constructorVkHash,
contractDeploymentData.functionTreeRoot,
contractDeploymentData.contractAddressSalt,
contractDeploymentData.portalContractAddress,
...toACVMCallContext(this.callContext),
...toACVMHistoricBlockData(this.historicBlockData),
...toACVMContractDeploymentData(contractDeploymentData),

this.txContext.chainId,
this.txContext.version,
Expand Down
25 changes: 10 additions & 15 deletions yarn-project/acir-simulator/src/public/public_execution_context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@ import { Fr } from '@aztec/foundation/fields';
import { createDebugLogger } from '@aztec/foundation/log';
import { FunctionL2Logs, UnencryptedL2Log } from '@aztec/types';

import { TypedOracle, toACVMWitness } from '../acvm/index.js';
import {
TypedOracle,
toACVMCallContext,
toACVMGlobalVariables,
toACVMHistoricBlockData,
toACVMWitness,
} from '../acvm/index.js';
import { PackedArgsCache, SideEffectCounter } from '../common/index.js';
import { CommitmentsDB, PublicContractsDB, PublicStateDB } from './db.js';
import { PublicExecution, PublicExecutionResult } from './execution.js';
Expand Down Expand Up @@ -50,20 +56,9 @@ export class PublicExecutionContext extends TypedOracle {
public getInitialWitness(witnessStartIndex = 1) {
const { callContext, args } = this.execution;
const fields = [
callContext.msgSender,
callContext.storageContractAddress,
callContext.portalContractAddress,
callContext.functionSelector.toField(),
callContext.isDelegateCall,
callContext.isStaticCall,
callContext.isContractDeployment,

...this.historicBlockData.toArray(),

this.globalVariables.chainId,
this.globalVariables.version,
this.globalVariables.blockNumber,
this.globalVariables.timestamp,
...toACVMCallContext(callContext),
...toACVMHistoricBlockData(this.historicBlockData),
...toACVMGlobalVariables(this.globalVariables),

...args,
];
Expand Down