Skip to content

Commit

Permalink
chore: Bytecode is buffer not string
Browse files Browse the repository at this point in the history
  • Loading branch information
spalladino committed Mar 22, 2024
1 parent 8ff82fe commit 3a7caff
Show file tree
Hide file tree
Showing 20 changed files with 38 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,12 @@ function serializeContractClassPublic(contractClass: Omit<ContractClassPublic, '
}

function serializePrivateFunction(fn: ExecutablePrivateFunctionWithMembershipProof): Buffer {
const bytecode = Buffer.from(fn.bytecode, 'base64');
return serializeToBuffer(
fn.selector,
fn.vkHash,
fn.isInternal,
bytecode.length,
bytecode,
fn.bytecode.length,
fn.bytecode,
fn.functionMetadataHash,
fn.artifactMetadataHash,
fn.unconstrainedFunctionsArtifactTreeRoot,
Expand Down Expand Up @@ -137,7 +136,7 @@ function deserializePrivateFunction(buffer: Buffer | BufferReader): ExecutablePr
selector: reader.readObject(FunctionSelector),
vkHash: reader.readObject(Fr),
isInternal: reader.readBoolean(),
bytecode: reader.readBuffer().toString('base64'),
bytecode: reader.readBuffer(),
functionMetadataHash: reader.readObject(Fr),
artifactMetadataHash: reader.readObject(Fr),
unconstrainedFunctionsArtifactTreeRoot: reader.readObject(Fr),
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/aztec.js/src/contract/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export function abiChecker(artifact: ContractArtifact) {
}

// TODO: implement a better check for bytecode (right now only checks if it's > 0)
if (!('bytecode' in func && typeof func.bytecode === 'string' && func.bytecode.length > 0)) {
if (!('bytecode' in func && func.bytecode.length > 0)) {
throw new Error('ABI function parameter has incorrect bytecode');
}

Expand Down
6 changes: 3 additions & 3 deletions yarn-project/aztec.js/src/contract/contract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ describe('Contract Class', () => {
},
],
returnTypes: [],
bytecode: '0af',
bytecode: Buffer.alloc(8, 0xfa),
},
{
name: 'baz',
Expand All @@ -72,7 +72,7 @@ describe('Contract Class', () => {
isInternal: false,
parameters: [],
returnTypes: [],
bytecode: '0be',
bytecode: Buffer.alloc(8, 0xfb),
debugSymbols: '',
},
{
Expand All @@ -96,7 +96,7 @@ describe('Contract Class', () => {
width: 32,
},
],
bytecode: '0cd',
bytecode: Buffer.alloc(8, 0xfc),
debugSymbols: '',
},
],
Expand Down
7 changes: 2 additions & 5 deletions yarn-project/aztec.js/src/deployment/broadcast_function.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export function broadcastPrivateFunction(

const vkHash = computeVerificationKeyHash(privateFunctionArtifact.verificationKey!);
const bytecode = bufferAsFields(
Buffer.from(privateFunctionArtifact.bytecode, 'base64'),
privateFunctionArtifact.bytecode,
MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS,
);

Expand Down Expand Up @@ -95,10 +95,7 @@ export function broadcastUnconstrainedFunction(
privateFunctionsArtifactTreeRoot,
} = createUnconstrainedFunctionMembershipProof(selector, artifact);

const bytecode = bufferAsFields(
Buffer.from(functionArtifact.bytecode, 'base64'),
MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS,
);
const bytecode = bufferAsFields(functionArtifact.bytecode, MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS);

const registerer = getRegistererContract(wallet);
return registerer.methods.broadcast_unconstrained_function(
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/circuits.js/src/contract/artifact_hash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export function computeFunctionArtifactHash(
| (Pick<FunctionArtifact, 'bytecode'> & { functionMetadataHash: Fr; selector: FunctionSelector }),
) {
const selector = 'selector' in fn ? fn.selector : FunctionSelector.fromNameAndParameters(fn);
const bytecodeHash = sha256Fr(Buffer.from(fn.bytecode, 'base64')).toBuffer();
const bytecodeHash = sha256Fr(fn.bytecode).toBuffer();
const metadataHash = 'functionMetadataHash' in fn ? fn.functionMetadataHash : computeFunctionMetadataHash(fn);
return sha256Fr(Buffer.concat([numToUInt8(VERSION), selector.toBuffer(), metadataHash.toBuffer(), bytecodeHash]));
}
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/circuits.js/src/contract/contract_class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export function getContractClassFromArtifact(
.filter(f => f.functionType === FunctionType.OPEN)
.map(f => ({
selector: FunctionSelector.fromNameAndParameters(f.name, f.parameters),
bytecode: Buffer.from(f.bytecode, 'base64'),
bytecode: f.bytecode,
isInternal: f.isInternal,
}))
.sort(cmpFunctionArtifacts);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export class PrivateFunctionBroadcastedEvent {
toFunctionWithMembershipProof(): ExecutablePrivateFunctionWithMembershipProof {
return {
...this.privateFunction,
bytecode: this.privateFunction.bytecode.toString('base64'),
bytecode: this.privateFunction.bytecode,
functionMetadataHash: this.privateFunction.metadataHash,
artifactMetadataHash: this.artifactMetadataHash,
unconstrainedFunctionsArtifactTreeRoot: this.unconstrainedFunctionsArtifactTreeRoot,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ describe('unconstrained_function_membership_proof', () => {

it('computes and verifies a proof', () => {
const proof = createUnconstrainedFunctionMembershipProof(selector, artifact);
const bytecode = Buffer.from(unconstrainedFunction.bytecode, 'base64');
const fn = { ...unconstrainedFunction, ...proof, bytecode, selector };
const fn = { ...unconstrainedFunction, ...proof, selector };
expect(isValidUnconstrainedFunctionMembershipProof(fn, contractClass)).toBeTruthy();
});

Expand All @@ -38,8 +37,7 @@ describe('unconstrained_function_membership_proof', () => {
const original = proof[field];
const mangled = Array.isArray(original) ? [Fr.random(), ...original.slice(1)] : Fr.random();
const wrong = { ...proof, [field]: mangled };
const bytecode = Buffer.from(unconstrainedFunction.bytecode, 'base64');
const fn = { ...unconstrainedFunction, ...wrong, bytecode, selector, vkHash };
const fn = { ...unconstrainedFunction, ...wrong, selector, vkHash };
expect(isValidUnconstrainedFunctionMembershipProof(fn, contractClass)).toBeFalsy();
},
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export function isValidUnconstrainedFunctionMembershipProof(
) {
const log = createDebugLogger('aztec:circuits:function_membership_proof');

const functionArtifactHash = computeFunctionArtifactHash({ ...fn, bytecode: fn.bytecode.toString('base64') });
const functionArtifactHash = computeFunctionArtifactHash(fn);
const computedArtifactFunctionTreeRoot = Fr.fromBuffer(
computeRootFromSiblingPath(
functionArtifactHash.toBuffer(),
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/circuits.js/src/tests/factories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1275,7 +1275,7 @@ export function makeExecutablePrivateFunctionWithMembershipProof(
): ExecutablePrivateFunctionWithMembershipProof {
return {
selector: makeSelector(seed),
bytecode: makeBytes(100, seed + 1).toString('base64'),
bytecode: makeBytes(100, seed + 1),
artifactTreeSiblingPath: makeTuple(3, fr, seed + 2),
artifactTreeLeafIndex: seed + 2,
privateFunctionTreeSiblingPath: makeTuple(3, fr, seed + 3),
Expand Down
4 changes: 2 additions & 2 deletions yarn-project/cli/src/cmds/inspect_contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ function logFunction(fn: FunctionArtifact, log: LogFn) {
const signatureWithParameterNames = decodeFunctionSignatureWithParameterNames(fn.name, fn.parameters);
const signature = decodeFunctionSignature(fn.name, fn.parameters);
const selector = FunctionSelector.fromSignature(signature);
const bytecodeSize = Buffer.from(fn.bytecode, 'base64').length;
const bytecodeHash = sha256(Buffer.from(fn.bytecode, 'base64')).toString('hex');
const bytecodeSize = fn.bytecode.length;
const bytecodeHash = sha256(fn.bytecode).toString('hex');
log(
`${fn.functionType} ${signatureWithParameterNames} \n\tfunction signature: ${signature}\n\tselector: ${selector}\n\tbytecode: ${bytecodeSize} bytes (sha256 ${bytecodeHash})`,
);
Expand Down
4 changes: 2 additions & 2 deletions yarn-project/cli/src/test/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const mockContractArtifact: ContractArtifact = {
},
],
returnTypes: [],
bytecode: 'constructorBytecode',
bytecode: Buffer.alloc(8, 0xfa),
debugSymbols: '',
},
{
Expand Down Expand Up @@ -61,7 +61,7 @@ export const mockContractArtifact: ContractArtifact = {
},
],
returnTypes: [{ kind: 'boolean' }],
bytecode: 'mockBytecode',
bytecode: Buffer.alloc(8, 0xfa),
debugSymbols: '',
},
],
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/foundation/src/abi/abi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ export interface FunctionArtifact extends FunctionAbi {
/**
* The ACIR bytecode of the function.
*/
bytecode: string;
bytecode: Buffer;
/**
* The verification key of the function.
*/
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/simulator/src/avm/avm_simulator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -704,5 +704,5 @@ function getAvmTestContractBytecode(functionName: string): Buffer {
!!artifact?.bytecode,
`No bytecode found for function ${functionName}. Try re-running bootstrap.sh on the repository root.`,
);
return Buffer.from(artifact.bytecode, 'base64');
return artifact.bytecode;
}
2 changes: 1 addition & 1 deletion yarn-project/simulator/src/client/private_execution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export async function executePrivateFunction(
): Promise<ExecutionResult> {
const functionSelector = functionData.selector;
log(`Executing external function ${contractAddress}:${functionSelector}(${artifact.name})`);
const acir = Buffer.from(artifact.bytecode, 'base64');
const acir = artifact.bytecode;
const initialWitness = context.getInitialWitness(artifact);
const acvmCallback = new Oracle(context);
const { partialWitness } = await acvm(await AcirSimulator.getSolver(), acir, initialWitness, acvmCallback).catch(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export async function executeUnconstrainedFunction(
const functionSelector = functionData.selector;
log(`Executing unconstrained function ${contractAddress}:${functionSelector}`);

const acir = Buffer.from(artifact.bytecode, 'base64');
const acir = artifact.bytecode;
const initialWitness = toACVMWitness(0, args);
const { partialWitness } = await acvm(
await AcirSimulator.getSolver(),
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/simulator/src/public/avm_executor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ describe('AVM WitGen and Proof Generation', () => {
const args: Fr[] = [new Fr(1), new Fr(2)];

const addArtifact = AvmTestContractArtifact.functions.find(f => f.name === 'add_args_return')!;
const bytecode = Buffer.from(addArtifact.bytecode, 'base64');
const bytecode = addArtifact.bytecode;
publicContracts.getBytecode.mockResolvedValue(bytecode);
const functionData = FunctionData.fromAbi(addArtifact);
const execution: PublicExecution = { contractAddress, functionData, args, callContext };
Expand Down
20 changes: 10 additions & 10 deletions yarn-project/simulator/src/public/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ describe('ACIR public execution simulator', () => {
sideEffectCounter: 0,
});

publicContracts.getBytecode.mockResolvedValue(Buffer.from(mintArtifact.bytecode, 'base64'));
publicContracts.getBytecode.mockResolvedValue(mintArtifact.bytecode);

// Mock the old value for the recipient balance to be 20
const isMinter = new Fr(1n); // 1n means true
Expand Down Expand Up @@ -188,7 +188,7 @@ describe('ACIR public execution simulator', () => {
recipientStorageSlot = computeSlotForMapping(new Fr(6n), recipient);
senderStorageSlot = computeSlotForMapping(new Fr(6n), sender);

publicContracts.getBytecode.mockResolvedValue(Buffer.from(transferArtifact.bytecode, 'base64'));
publicContracts.getBytecode.mockResolvedValue(transferArtifact.bytecode);

execution = { contractAddress, functionData, args, callContext };
});
Expand Down Expand Up @@ -275,9 +275,9 @@ describe('ACIR public execution simulator', () => {
// eslint-disable-next-line require-await
publicContracts.getBytecode.mockImplementation(async (addr: AztecAddress, selector: FunctionSelector) => {
if (addr.equals(parentContractAddress) && selector.equals(parentEntryPointFnSelector)) {
return Buffer.from(parentEntryPointFn.bytecode, 'base64');
return parentEntryPointFn.bytecode;
} else if (addr.equals(childContractAddress) && selector.equals(childValueFnSelector)) {
return Buffer.from(childValueFn.bytecode, 'base64');
return childValueFn.bytecode;
} else {
return undefined;
}
Expand Down Expand Up @@ -337,7 +337,7 @@ describe('ACIR public execution simulator', () => {
sideEffectCounter: 0,
});

publicContracts.getBytecode.mockResolvedValue(Buffer.from(shieldArtifact.bytecode, 'base64'));
publicContracts.getBytecode.mockResolvedValue(shieldArtifact.bytecode);
// mock initial balance to be greater than the amount being sent
publicState.storageRead.mockResolvedValue(amount);

Expand Down Expand Up @@ -371,7 +371,7 @@ describe('ACIR public execution simulator', () => {
sideEffectCounter: 0,
});

publicContracts.getBytecode.mockResolvedValue(Buffer.from(createL2ToL1MessagePublicArtifact.bytecode, 'base64'));
publicContracts.getBytecode.mockResolvedValue(createL2ToL1MessagePublicArtifact.bytecode);

const execution: PublicExecution = { contractAddress, functionData, args, callContext };
const result = await executor.simulate(execution, GlobalVariables.empty());
Expand Down Expand Up @@ -401,7 +401,7 @@ describe('ACIR public execution simulator', () => {
sideEffectCounter: 0,
});

publicContracts.getBytecode.mockResolvedValue(Buffer.from(createNullifierPublicArtifact.bytecode, 'base64'));
publicContracts.getBytecode.mockResolvedValue(createNullifierPublicArtifact.bytecode);

const execution: PublicExecution = { contractAddress, functionData, args, callContext };
const result = await executor.simulate(execution, GlobalVariables.empty());
Expand Down Expand Up @@ -469,7 +469,7 @@ describe('ACIR public execution simulator', () => {
);

const mockOracles = (updateState = true) => {
publicContracts.getBytecode.mockResolvedValue(Buffer.from(mintPublicArtifact.bytecode, 'base64'));
publicContracts.getBytecode.mockResolvedValue(mintPublicArtifact.bytecode);
publicState.storageRead.mockResolvedValue(Fr.ZERO);

const siblingPathBuffers = Array(L1_TO_L2_MSG_TREE_HEIGHT)
Expand Down Expand Up @@ -661,7 +661,7 @@ describe('ACIR public execution simulator', () => {
});

beforeEach(() => {
publicContracts.getBytecode.mockResolvedValue(Buffer.from(assertGlobalVarsArtifact.bytecode, 'base64'));
publicContracts.getBytecode.mockResolvedValue(assertGlobalVarsArtifact.bytecode);
});

// Note: Order here has to match the order of the properties in GlobalVariables.getFields(...) function.
Expand Down Expand Up @@ -744,7 +744,7 @@ describe('ACIR public execution simulator', () => {
});

beforeEach(() => {
publicContracts.getBytecode.mockResolvedValue(Buffer.from(assertHeaderPublicArtifact.bytecode, 'base64'));
publicContracts.getBytecode.mockResolvedValue(assertHeaderPublicArtifact.bytecode);
});

it('Header is correctly set', () => {
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/types/src/abi/contract_artifact.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ function generateFunctionArtifact(fn: NoirCompiledContractFunction): FunctionArt
isInitializer: fn.custom_attributes.includes(AZTEC_INITIALIZER_ATTRIBUTE),
parameters,
returnTypes,
bytecode: fn.bytecode,
bytecode: Buffer.from(fn.bytecode, 'base64'),
verificationKey: mockVerificationKey,
debugSymbols: fn.debug_symbols,
};
Expand Down
4 changes: 2 additions & 2 deletions yarn-project/types/src/contracts/contract_class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ export type ContractClassPublic = {

/** Private function definition with executable bytecode. */
export interface ExecutablePrivateFunction extends PrivateFunction {
/** ACIR and Brillig bytecode in b64 */
bytecode: string; // TODO(@spalladino) Use buffer for bytecode everywhere
/** ACIR and Brillig bytecode */
bytecode: Buffer;
}

/** Sibling paths and sibling commitments for proving membership of a private function within a contract class. */
Expand Down

0 comments on commit 3a7caff

Please sign in to comment.