From ce8aceb6076ce5e006ef448bff97263dabe04032 Mon Sep 17 00:00:00 2001 From: Maddiaa0 <47148561+Maddiaa0@users.noreply.github.com> Date: Mon, 29 Jan 2024 22:53:57 +0000 Subject: [PATCH] fix --- .../src/avm/opcodes/control_flow.test.ts | 225 +++++++++--------- .../src/avm/opcodes/control_flow.ts | 10 +- 2 files changed, 117 insertions(+), 118 deletions(-) diff --git a/yarn-project/acir-simulator/src/avm/opcodes/control_flow.test.ts b/yarn-project/acir-simulator/src/avm/opcodes/control_flow.test.ts index b5718b11231b..7c04e08f246c 100644 --- a/yarn-project/acir-simulator/src/avm/opcodes/control_flow.test.ts +++ b/yarn-project/acir-simulator/src/avm/opcodes/control_flow.test.ts @@ -1,3 +1,5 @@ +import { Fr } from '@aztec/foundation/fields'; + import { MockProxy, mock } from 'jest-mock-extended'; import { AvmMachineState } from '../avm_machine_state.js'; @@ -24,137 +26,136 @@ describe('Control Flow Opcodes', () => { it('Should implement JUMP', async () => { const jumpLocation = 22; - expect(machineState.pc).toBe(0); - - const instruction = new Jump(jumpLocation); - await instruction.execute(machineState, journal); - expect(machineState.pc).toBe(jumpLocation); - }); - - it('Should implement JUMPI - truthy', async () => { - const jumpLocation = 22; - const jumpLocation1 = 69; + expect(machineState.pc).toBe(0); - expect(machineState.pc).toBe(0); + const instruction = new Jump(jumpLocation); + await instruction.execute(machineState, journal); + expect(machineState.pc).toBe(jumpLocation); + }); - machineState.memory.set(0, new Uint16(1n)); - machineState.memory.set(1, new Uint16(2n)); + it('Should implement JUMPI - truthy', async () => { + const jumpLocation = 22; + const jumpLocation1 = 69; - const instruction = new JumpI(jumpLocation, 0); - await instruction.execute(machineState, journal); - expect(machineState.pc).toBe(jumpLocation); + expect(machineState.pc).toBe(0); - // Truthy can be greater than 1 - const instruction1 = new JumpI(jumpLocation1, 1); - await instruction1.execute(machineState, journal); - expect(machineState.pc).toBe(jumpLocation1); - }); + machineState.memory.set(0, new Uint16(1n)); + machineState.memory.set(1, new Uint16(2n)); - it('Should implement JUMPI - falsy', async () => { - const jumpLocation = 22; + const instruction = new JumpI(jumpLocation, 0); + await instruction.execute(machineState, journal); + expect(machineState.pc).toBe(jumpLocation); - expect(machineState.pc).toBe(0); + // Truthy can be greater than 1 + const instruction1 = new JumpI(jumpLocation1, 1); + await instruction1.execute(machineState, journal); + expect(machineState.pc).toBe(jumpLocation1); + }); - machineState.memory.set(0, new Uint16(0n)); + it('Should implement JUMPI - falsy', async () => { + const jumpLocation = 22; - const instruction = new JumpI(jumpLocation, 0); - await instruction.execute(machineState, journal); - expect(machineState.pc).toBe(1); - }); + expect(machineState.pc).toBe(0); - it('Should implement Internal Call and Return', async () => { - const jumpLocation = 22; + machineState.memory.set(0, new Uint16(0n)); - expect(machineState.pc).toBe(0); + const instruction = new JumpI(jumpLocation, 0); + await instruction.execute(machineState, journal); + expect(machineState.pc).toBe(1); + }); - const instruction = new InternalCall(jumpLocation); - const returnInstruction = new InternalReturn(); + it('Should implement Internal Call and Return', async () => { + const jumpLocation = 22; - await instruction.execute(machineState, journal); - expect(machineState.pc).toBe(jumpLocation); + expect(machineState.pc).toBe(0); - await returnInstruction.execute(machineState, journal); - expect(machineState.pc).toBe(1); - }); + const instruction = new InternalCall(jumpLocation); + const returnInstruction = new InternalReturn(); - it('Should chain series of control flow instructions', async () => { - const jumpLocation0 = 22; - const jumpLocation1 = 69; - const jumpLocation2 = 1337; - - const aloneJumpLocation = 420; - - const instructions = [ - // pc | internal call stack - new InternalCall(jumpLocation0), // 22 | [1] - new InternalCall(jumpLocation1), // 69 | [1, 23] - new InternalReturn(), // 23 | [1] - new Jump(aloneJumpLocation), // 420 | [1] - new InternalCall(jumpLocation2), // 1337| [1, 421] - new InternalReturn(), // 421 | [1] - new InternalReturn(), // 1 | [] - ]; - - // The expected program counter after each instruction is invoked - const expectedPcs = [ - jumpLocation0, - jumpLocation1, - jumpLocation0 + 1, - aloneJumpLocation, - jumpLocation2, - aloneJumpLocation + 1, - 1, - ]; - - for (let i = 0; i < instructions.length; i++) { - await instructions[i].execute(machineState, journal); - expect(machineState.pc).toBe(expectedPcs[i]); - } - }); + await instruction.execute(machineState, journal); + expect(machineState.pc).toBe(jumpLocation); - it('Should error if Internal Return is called without a corresponding Internal Call', async () => { - const returnInstruction = () => new InternalReturn().execute(machineState, journal); - await expect(returnInstruction()).rejects.toThrow(InstructionExecutionError); - }); + await returnInstruction.execute(machineState, journal); + expect(machineState.pc).toBe(1); + }); - it('Should increment PC on All other Instructions', async () => { - const instructions = [ - new Add(0, 1, 2), - new Sub(0, 1, 2), - new Mul(0, 1, 2), - new Lt(TypeTag.UINT16, 0, 1, 2), - new Lte(TypeTag.UINT16, 0, 1, 2), - new Eq(TypeTag.UINT16, 0, 1, 2), - new Xor(TypeTag.UINT16, 0, 1, 2), - new And(TypeTag.UINT16, 0, 1, 2), - new Or(TypeTag.UINT16, 0, 1, 2), - new Shl(TypeTag.UINT16, 0, 1, 2), - new Shr(TypeTag.UINT16, 0, 1, 2), - new Not(TypeTag.UINT16, 0, 2), - new CalldataCopy(0, 1, 2), - new Set(TypeTag.UINT16, 0n, 1), - new Mov(0, 1), - new CMov(0, 1, 2, 3), - new Cast(TypeTag.UINT16, 0, 1), - ]; - - for (const instruction of instructions) { - // Use a fresh machine state each run - const innerMachineState = new AvmMachineState(initExecutionEnvironment()); - innerMachineState.memory.set(0, new Uint16(4n)); - innerMachineState.memory.set(1, new Uint16(8n)); - innerMachineState.memory.set(2, new Uint16(12n)); - expect(machineState.pc).toBe(0); + it('Should chain series of control flow instructions', async () => { + const jumpLocation0 = 22; + const jumpLocation1 = 69; + const jumpLocation2 = 1337; + + const aloneJumpLocation = 420; + + const instructions = [ + // pc | internal call stack + new InternalCall(jumpLocation0), // 22 | [1] + new InternalCall(jumpLocation1), // 69 | [1, 23] + new InternalReturn(), // 23 | [1] + new Jump(aloneJumpLocation), // 420 | [1] + new InternalCall(jumpLocation2), // 1337| [1, 421] + new InternalReturn(), // 421 | [1] + new InternalReturn(), // 1 | [] + ]; + + // The expected program counter after each instruction is invoked + const expectedPcs = [ + jumpLocation0, + jumpLocation1, + jumpLocation0 + 1, + aloneJumpLocation, + jumpLocation2, + aloneJumpLocation + 1, + 1, + ]; + + for (let i = 0; i < instructions.length; i++) { + await instructions[i].execute(machineState, journal); + expect(machineState.pc).toBe(expectedPcs[i]); + } + }); - await instruction.execute(machineState, journal); - } - }); + it('Should error if Internal Return is called without a corresponding Internal Call', async () => { + const returnInstruction = () => new InternalReturn().execute(machineState, journal); + await expect(returnInstruction()).rejects.toThrow(InstructionExecutionError); + }); + it('Should increment PC on All other Instructions', async () => { + const instructions = [ + new Add(0, 1, 2), + new Sub(0, 1, 2), + new Mul(0, 1, 2), + new Lt(TypeTag.UINT16, 0, 1, 2), + new Lte(TypeTag.UINT16, 0, 1, 2), + new Eq(TypeTag.UINT16, 0, 1, 2), + new Xor(TypeTag.UINT16, 0, 1, 2), + new And(TypeTag.UINT16, 0, 1, 2), + new Or(TypeTag.UINT16, 0, 1, 2), + new Shl(TypeTag.UINT16, 0, 1, 2), + new Shr(TypeTag.UINT16, 0, 1, 2), + new Not(TypeTag.UINT16, 0, 2), + new CalldataCopy(0, 1, 2), + new Set(TypeTag.UINT16, 0n, 1), + new Mov(0, 1), + new CMov(0, 1, 2, 3), + new Cast(TypeTag.UINT16, 0, 1), + ]; + + for (const instruction of instructions) { + // Use a fresh machine state each run + const innerMachineState = new AvmMachineState(initExecutionEnvironment()); + innerMachineState.memory.set(0, new Uint16(4n)); + innerMachineState.memory.set(1, new Uint16(8n)); + innerMachineState.memory.set(2, new Uint16(12n)); + expect(innerMachineState.pc).toBe(0); + + await instruction.execute(innerMachineState, journal); + } + }); }); describe('Halting Opcodes', () => { it('Should return data from the return opcode', async () => { - const returnData = [new Field(1n), new Field(2n), new Field(3n)]; + const returnData = [new Fr(1n), new Fr(2n), new Fr(3n)]; machineState.memory.set(0, new Field(1n)); machineState.memory.set(1, new Field(2n)); @@ -169,10 +170,10 @@ describe('Control Flow Opcodes', () => { }); it('Should return data and revert from the revert opcode', async () => { - const returnData = [new Field(1n), new Field(2n), new Field(3n)]; + const returnData = [new Fr(1n), new Fr(2n), new Fr(3n)]; - machineState.memory.set(0, new Field(1n)); - machineState.memory.set(1, new Field(2n)); + machineState.memory.set(0, new Field(1n)); + machineState.memory.set(1, new Field(2n)); machineState.memory.set(2, new Field(3n)); const instruction = new Revert(0, returnData.length); diff --git a/yarn-project/acir-simulator/src/avm/opcodes/control_flow.ts b/yarn-project/acir-simulator/src/avm/opcodes/control_flow.ts index 1f3063d3e587..c890fc700e31 100644 --- a/yarn-project/acir-simulator/src/avm/opcodes/control_flow.ts +++ b/yarn-project/acir-simulator/src/avm/opcodes/control_flow.ts @@ -1,5 +1,3 @@ -import { Fr } from '@aztec/foundation/fields'; - import { AvmMachineState } from '../avm_machine_state.js'; import { IntegralValue } from '../avm_memory_types.js'; import { AvmJournal } from '../journal/journal.js'; @@ -14,9 +12,7 @@ export class Return extends Instruction { } async execute(machineState: AvmMachineState, _journal: AvmJournal): Promise { - const returnData = machineState.memory - .getSlice(this.returnOffset, this.copySize) - .map(word => new Fr(word.toBigInt())); + const returnData = machineState.memory.getSlice(this.returnOffset, this.copySize).map(word => word.toFr()); machineState.setReturnData(returnData); @@ -33,7 +29,9 @@ export class Revert extends Instruction { } async execute(machineState: AvmMachineState, _journal: AvmJournal): Promise { - const returnData = machineState.readMemoryChunk(this.returnOffset, this.returnOffset + this.retSize); + const returnData = machineState.memory + .getSlice(this.returnOffset, this.returnOffset + this.retSize) + .map(word => word.toFr()); machineState.setReturnData(returnData); this.revert(machineState);