From 6e31eb17fef4a033de4291e3f70644be3311491c Mon Sep 17 00:00:00 2001 From: dbanks12 Date: Wed, 27 Nov 2024 20:28:40 +0000 Subject: [PATCH] feat_exceptional halts_ in AVM (like div/0) consume all remaining allocated gas --- .../simulator/src/avm/avm_simulator.test.ts | 20 +++++++++++++++++-- .../simulator/src/avm/avm_simulator.ts | 6 ++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/yarn-project/simulator/src/avm/avm_simulator.test.ts b/yarn-project/simulator/src/avm/avm_simulator.test.ts index 06811af15577..b1dd154c035e 100644 --- a/yarn-project/simulator/src/avm/avm_simulator.test.ts +++ b/yarn-project/simulator/src/avm/avm_simulator.test.ts @@ -58,6 +58,7 @@ import { SStore, SendL2ToL1Message, Set, + Div, } from './opcodes/index.js'; import { encodeToBytecode } from './serialization/bytecode_serialization.js'; import { Opcode } from './serialization/instruction_serialization.js'; @@ -111,8 +112,23 @@ describe('AVM simulator: injected bytecode', () => { expect(results.reverted).toBe(true); expect(results.output).toEqual([]); expect(results.revertReason?.message).toEqual('Not enough L2GAS gas left'); - expect(context.machineState.l2GasLeft).toEqual(0); - expect(context.machineState.daGasLeft).toEqual(0); + expect(results.gasLeft.l2Gas).toEqual(0); + expect(results.gasLeft.daGas).toEqual(0); + }); + + it('An exceptional halt should consume all allocated gas', async () => { + const context = initContext(); + + // should halt with tag mismatch + const badBytecode = encodeToBytecode([ + new Div(/*indirect=*/ 0, /*aOffset=*/ 0, /*bOffset=*/ 0, /*dstOffset=*/ 0).as(Opcode.DIV_8, Div.wireFormat8), + ]); + const results = await new AvmSimulator(context).executeBytecode(markBytecodeAsAvm(badBytecode)); + expect(results.reverted).toBe(true); + expect(results.output).toEqual([]); + expect(results.revertReason?.message).toMatch(/Tag mismatch/); + expect(results.gasLeft.l2Gas).toEqual(0); + expect(results.gasLeft.daGas).toEqual(0); }); }); diff --git a/yarn-project/simulator/src/avm/avm_simulator.ts b/yarn-project/simulator/src/avm/avm_simulator.ts index 643fae72da0c..b392602e7e54 100644 --- a/yarn-project/simulator/src/avm/avm_simulator.ts +++ b/yarn-project/simulator/src/avm/avm_simulator.ts @@ -109,7 +109,7 @@ export class AvmSimulator { return new AvmContractCallResult( /*reverted=*/ true, /*output=*/ [], - /*gasLeft=*/ { l2Gas: 0, daGas: 0 }, + /*gasLeft=*/ { l2Gas: 0, daGas: 0 }, // consumes all allocated gas revertReason, ); } @@ -190,8 +190,10 @@ export class AvmSimulator { } const revertReason = revertReasonFromExceptionalHalt(err, this.context); + // Exceptional halts consume all allocated gas + const noGasLeft = { l2Gas: 0, daGas: 0, }; // Note: "exceptional halts" cannot return data, hence []. - const results = new AvmContractCallResult(/*reverted=*/ true, /*output=*/ [], machineState.gasLeft, revertReason); + const results = new AvmContractCallResult(/*reverted=*/ true, /*output=*/ [], noGasLeft, revertReason); this.log.debug(`Context execution results: ${results.toString()}`); this.tallyPrintFunction();