From 3a7caffda0b47e5b41be18f8b17b5e1f2d4b2c19 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Wed, 20 Mar 2024 18:51:21 -0300 Subject: [PATCH] chore: Bytecode is buffer not string --- .../kv_archiver_store/contract_class_store.ts | 7 +++---- yarn-project/aztec.js/src/contract/checker.ts | 2 +- .../aztec.js/src/contract/contract.test.ts | 6 +++--- .../src/deployment/broadcast_function.ts | 7 ++----- .../circuits.js/src/contract/artifact_hash.ts | 2 +- .../src/contract/contract_class.ts | 2 +- .../private_function_broadcasted_event.ts | 2 +- ...strained_function_membership_proof.test.ts | 6 ++---- ...unconstrained_function_membership_proof.ts | 2 +- .../circuits.js/src/tests/factories.ts | 2 +- yarn-project/cli/src/cmds/inspect_contract.ts | 4 ++-- yarn-project/cli/src/test/mocks.ts | 4 ++-- yarn-project/foundation/src/abi/abi.ts | 2 +- .../simulator/src/avm/avm_simulator.test.ts | 2 +- .../simulator/src/client/private_execution.ts | 2 +- .../src/client/unconstrained_execution.ts | 2 +- .../simulator/src/public/avm_executor.test.ts | 2 +- .../simulator/src/public/index.test.ts | 20 +++++++++---------- .../types/src/abi/contract_artifact.ts | 2 +- .../types/src/contracts/contract_class.ts | 4 ++-- 20 files changed, 38 insertions(+), 44 deletions(-) diff --git a/yarn-project/archiver/src/archiver/kv_archiver_store/contract_class_store.ts b/yarn-project/archiver/src/archiver/kv_archiver_store/contract_class_store.ts index 9efd33aec1df..f446372b021c 100644 --- a/yarn-project/archiver/src/archiver/kv_archiver_store/contract_class_store.ts +++ b/yarn-project/archiver/src/archiver/kv_archiver_store/contract_class_store.ts @@ -82,13 +82,12 @@ function serializeContractClassPublic(contractClass: Omit 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'); } diff --git a/yarn-project/aztec.js/src/contract/contract.test.ts b/yarn-project/aztec.js/src/contract/contract.test.ts index 90e822a8f8e5..7b2c692385da 100644 --- a/yarn-project/aztec.js/src/contract/contract.test.ts +++ b/yarn-project/aztec.js/src/contract/contract.test.ts @@ -63,7 +63,7 @@ describe('Contract Class', () => { }, ], returnTypes: [], - bytecode: '0af', + bytecode: Buffer.alloc(8, 0xfa), }, { name: 'baz', @@ -72,7 +72,7 @@ describe('Contract Class', () => { isInternal: false, parameters: [], returnTypes: [], - bytecode: '0be', + bytecode: Buffer.alloc(8, 0xfb), debugSymbols: '', }, { @@ -96,7 +96,7 @@ describe('Contract Class', () => { width: 32, }, ], - bytecode: '0cd', + bytecode: Buffer.alloc(8, 0xfc), debugSymbols: '', }, ], diff --git a/yarn-project/aztec.js/src/deployment/broadcast_function.ts b/yarn-project/aztec.js/src/deployment/broadcast_function.ts index edbff33220e7..e748629b5ad8 100644 --- a/yarn-project/aztec.js/src/deployment/broadcast_function.ts +++ b/yarn-project/aztec.js/src/deployment/broadcast_function.ts @@ -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, ); @@ -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( diff --git a/yarn-project/circuits.js/src/contract/artifact_hash.ts b/yarn-project/circuits.js/src/contract/artifact_hash.ts index a6b5dc37d515..f07138eb1673 100644 --- a/yarn-project/circuits.js/src/contract/artifact_hash.ts +++ b/yarn-project/circuits.js/src/contract/artifact_hash.ts @@ -94,7 +94,7 @@ export function computeFunctionArtifactHash( | (Pick & { 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])); } diff --git a/yarn-project/circuits.js/src/contract/contract_class.ts b/yarn-project/circuits.js/src/contract/contract_class.ts index 5d79acab8814..a8529ac39928 100644 --- a/yarn-project/circuits.js/src/contract/contract_class.ts +++ b/yarn-project/circuits.js/src/contract/contract_class.ts @@ -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); diff --git a/yarn-project/circuits.js/src/contract/events/private_function_broadcasted_event.ts b/yarn-project/circuits.js/src/contract/events/private_function_broadcasted_event.ts index f512fd64125c..9fb9569e3c7f 100644 --- a/yarn-project/circuits.js/src/contract/events/private_function_broadcasted_event.ts +++ b/yarn-project/circuits.js/src/contract/events/private_function_broadcasted_event.ts @@ -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, diff --git a/yarn-project/circuits.js/src/contract/unconstrained_function_membership_proof.test.ts b/yarn-project/circuits.js/src/contract/unconstrained_function_membership_proof.test.ts index 27cf66b238f5..661211978e31 100644 --- a/yarn-project/circuits.js/src/contract/unconstrained_function_membership_proof.test.ts +++ b/yarn-project/circuits.js/src/contract/unconstrained_function_membership_proof.test.ts @@ -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(); }); @@ -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(); }, ); diff --git a/yarn-project/circuits.js/src/contract/unconstrained_function_membership_proof.ts b/yarn-project/circuits.js/src/contract/unconstrained_function_membership_proof.ts index 00c1b660cf7d..144e11ed81d5 100644 --- a/yarn-project/circuits.js/src/contract/unconstrained_function_membership_proof.ts +++ b/yarn-project/circuits.js/src/contract/unconstrained_function_membership_proof.ts @@ -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(), diff --git a/yarn-project/circuits.js/src/tests/factories.ts b/yarn-project/circuits.js/src/tests/factories.ts index 383fa0d83e90..829c7efc558f 100644 --- a/yarn-project/circuits.js/src/tests/factories.ts +++ b/yarn-project/circuits.js/src/tests/factories.ts @@ -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), diff --git a/yarn-project/cli/src/cmds/inspect_contract.ts b/yarn-project/cli/src/cmds/inspect_contract.ts index a5fb4ca52631..4728de02fd08 100644 --- a/yarn-project/cli/src/cmds/inspect_contract.ts +++ b/yarn-project/cli/src/cmds/inspect_contract.ts @@ -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})`, ); diff --git a/yarn-project/cli/src/test/mocks.ts b/yarn-project/cli/src/test/mocks.ts index b1463de3acd8..afa693b8427c 100644 --- a/yarn-project/cli/src/test/mocks.ts +++ b/yarn-project/cli/src/test/mocks.ts @@ -18,7 +18,7 @@ export const mockContractArtifact: ContractArtifact = { }, ], returnTypes: [], - bytecode: 'constructorBytecode', + bytecode: Buffer.alloc(8, 0xfa), debugSymbols: '', }, { @@ -61,7 +61,7 @@ export const mockContractArtifact: ContractArtifact = { }, ], returnTypes: [{ kind: 'boolean' }], - bytecode: 'mockBytecode', + bytecode: Buffer.alloc(8, 0xfa), debugSymbols: '', }, ], diff --git a/yarn-project/foundation/src/abi/abi.ts b/yarn-project/foundation/src/abi/abi.ts index d8ba0f8a7e4f..c131a81f9263 100644 --- a/yarn-project/foundation/src/abi/abi.ts +++ b/yarn-project/foundation/src/abi/abi.ts @@ -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. */ diff --git a/yarn-project/simulator/src/avm/avm_simulator.test.ts b/yarn-project/simulator/src/avm/avm_simulator.test.ts index fc703ed3eac7..bf85390f1cb2 100644 --- a/yarn-project/simulator/src/avm/avm_simulator.test.ts +++ b/yarn-project/simulator/src/avm/avm_simulator.test.ts @@ -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; } diff --git a/yarn-project/simulator/src/client/private_execution.ts b/yarn-project/simulator/src/client/private_execution.ts index 1491b7d7dcb5..5083874ef23a 100644 --- a/yarn-project/simulator/src/client/private_execution.ts +++ b/yarn-project/simulator/src/client/private_execution.ts @@ -24,7 +24,7 @@ export async function executePrivateFunction( ): Promise { 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( diff --git a/yarn-project/simulator/src/client/unconstrained_execution.ts b/yarn-project/simulator/src/client/unconstrained_execution.ts index 0ecfb7e55382..19b78bec0f5a 100644 --- a/yarn-project/simulator/src/client/unconstrained_execution.ts +++ b/yarn-project/simulator/src/client/unconstrained_execution.ts @@ -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(), diff --git a/yarn-project/simulator/src/public/avm_executor.test.ts b/yarn-project/simulator/src/public/avm_executor.test.ts index 0954b5fe975f..23f31610c1af 100644 --- a/yarn-project/simulator/src/public/avm_executor.test.ts +++ b/yarn-project/simulator/src/public/avm_executor.test.ts @@ -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 }; diff --git a/yarn-project/simulator/src/public/index.test.ts b/yarn-project/simulator/src/public/index.test.ts index 01a2cbe946a3..69acb83362f5 100644 --- a/yarn-project/simulator/src/public/index.test.ts +++ b/yarn-project/simulator/src/public/index.test.ts @@ -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 @@ -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 }; }); @@ -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; } @@ -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); @@ -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()); @@ -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()); @@ -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) @@ -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. @@ -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', () => { diff --git a/yarn-project/types/src/abi/contract_artifact.ts b/yarn-project/types/src/abi/contract_artifact.ts index 04f820181948..22ac7a7df8c6 100644 --- a/yarn-project/types/src/abi/contract_artifact.ts +++ b/yarn-project/types/src/abi/contract_artifact.ts @@ -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, }; diff --git a/yarn-project/types/src/contracts/contract_class.ts b/yarn-project/types/src/contracts/contract_class.ts index beeb10b66705..b6714bd03c49 100644 --- a/yarn-project/types/src/contracts/contract_class.ts +++ b/yarn-project/types/src/contracts/contract_class.ts @@ -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. */