Skip to content

Commit

Permalink
chore(avm): disable mem gas accounting (#6862)
Browse files Browse the repository at this point in the history
Calculating complex opcode-dependent gas in the AVM is complex. Disable
for now.

After this PR, the simulator only uses the BaseGasCost table to assign
gas to opcodes (EXCEPT externalCall).

See #6861.

cc: @spalladino.
  • Loading branch information
fcarreiro authored Jun 4, 2024
1 parent 19aba3e commit 12b1b0e
Show file tree
Hide file tree
Showing 11 changed files with 85 additions and 117 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ describe('benchmarks/tx_size_fees', () => {
// non-rev: 1 nullifiers, overhead; rev: 2 note hashes, 1 nullifier, 1168 B enc note logs, 0 B enc logs,0 B unenc logs, teardown
// L2:
// non-rev: 0; rev: 0
200752420n,
200072320n,
],
[
'private fee',
Expand All @@ -81,7 +81,7 @@ describe('benchmarks/tx_size_fees', () => {
// non-rev: 3 nullifiers, overhead; rev: 2 note hashes, 1168 B enc note logs, 0 B enc logs, 0 B unenc logs, teardown
// L2:
// non-rev: 0; rev: 0
200243972n,
200036352n,
],
] as const)(
'sends a tx with a fee with %s payment method',
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/end-to-end/src/e2e_avm_simulator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ describe('e2e_avm_simulator', () => {
const l2GasUsed = simulation.publicOutput!.end.gasUsed.l2Gas! - l2TeardownAllocation;
// L2 gas used will vary a lot depending on codegen and other factors,
// so we just set a wide range for it, and check it's not a suspiciously round number.
expect(l2GasUsed).toBeGreaterThan(1e3);
expect(l2GasUsed).toBeGreaterThan(150);
expect(l2GasUsed).toBeLessThan(1e6);
expect(l2GasUsed! % 1000).not.toEqual(0);
});
Expand Down
8 changes: 4 additions & 4 deletions yarn-project/end-to-end/src/e2e_fees/private_payments.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,21 +123,21 @@ describe('e2e_fees private_payment', () => {
* 1160 bytes of logs = 1160 * DA_GAS_PER_BYTE = 1160 * 16 = 5568 DA gas
* tx overhead of 512 DA gas
* for a total of 21632 DA gas (without gas used during public execution)
* public execution uses 222340 gas
* for a total of 243972 gas
* public execution uses N gas
* for a total of 200036352 gas
*
* The default teardown gas allocation at present is
* 100_000_000 for both DA and L2 gas.
*
* That produces a grand total of 200243972n.
* That produces a grand total of 200036352.
*
* This will change because we are presently squashing notes/nullifiers across non/revertible during
* private execution, but we shouldn't.
*
* TODO(6583): update this comment properly now that public execution consumes gas
*/

expect(tx.transactionFee).toEqual(200243972n);
expect(tx.transactionFee).toEqual(200036352n);
await expect(t.getCoinbaseBalance()).resolves.toEqual(InitialSequencerL1Gas + tx.transactionFee!);
const [feeAmount, refundAmount] = getFeeAndRefund(tx);

Expand Down
4 changes: 2 additions & 2 deletions yarn-project/simulator/src/avm/avm_gas.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import { initContext } from './fixtures/index.js';
import { Add, CalldataCopy, Div, Mul, Set as SetInstruction, Sub } from './opcodes/index.js';
import { encodeToBytecode } from './serialization/bytecode_serialization.js';

describe('AVM simulator: dynamic gas costs per instruction', () => {
describe.skip('AVM simulator: dynamic gas costs per instruction', () => {
it.each([
// BASE_GAS(10) * 1 + MEMORY_WRITE(100) = 110
[new SetInstruction(/*indirect=*/ 0, /*inTag=*/ TypeTag.UINT8, /*value=*/ 1, /*dstOffset=*/ 0), [110, 0, 0]],
[new SetInstruction(/*indirect=*/ 0, /*inTag=*/ TypeTag.UINT8, /*value=*/ 1, /*dstOffset=*/ 0), [110, 0]],
// BASE_GAS(10) * 1 + MEMORY_WRITE(100) = 110
[new SetInstruction(/*indirect=*/ 0, /*inTag=*/ TypeTag.UINT32, /*value=*/ 1, /*dstOffset=*/ 0), [110]],
// BASE_GAS(10) * 1 + MEMORY_WRITE(100) = 110
Expand Down
139 changes: 66 additions & 73 deletions yarn-project/simulator/src/avm/avm_gas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,93 +49,86 @@ export const EmptyGas: Gas = {
/** Dimensions of gas usage: L1, L2, and DA. */
export const GasDimensions = ['l2Gas', 'daGas'] as const;

/** Null object to represent a gas cost that's dynamic instead of fixed for a given instruction. */
export const DynamicGasCost = Symbol('DynamicGasCost');

/** Temporary default gas cost. We should eventually remove all usage of this variable in favor of actual gas for each opcode. */
const TemporaryDefaultGasCost = { l2Gas: 10, daGas: 0 };
/** Default gas cost for an opcode. */
const DefaultBaseGasCost: Gas = { l2Gas: 10, daGas: 0 };

/** Base gas costs for each instruction. Additional gas cost may be added on top due to memory or storage accesses, etc. */
export const GasCosts: Record<Opcode, Gas | typeof DynamicGasCost> = {
[Opcode.ADD]: TemporaryDefaultGasCost,
[Opcode.SUB]: TemporaryDefaultGasCost,
[Opcode.MUL]: TemporaryDefaultGasCost,
[Opcode.DIV]: TemporaryDefaultGasCost,
[Opcode.FDIV]: TemporaryDefaultGasCost,
[Opcode.EQ]: TemporaryDefaultGasCost,
[Opcode.LT]: TemporaryDefaultGasCost,
[Opcode.LTE]: TemporaryDefaultGasCost,
[Opcode.AND]: TemporaryDefaultGasCost,
[Opcode.OR]: TemporaryDefaultGasCost,
[Opcode.XOR]: TemporaryDefaultGasCost,
[Opcode.NOT]: TemporaryDefaultGasCost,
[Opcode.SHL]: TemporaryDefaultGasCost,
[Opcode.SHR]: TemporaryDefaultGasCost,
[Opcode.CAST]: TemporaryDefaultGasCost,
const BaseGasCosts: Record<Opcode, Gas> = {
[Opcode.ADD]: DefaultBaseGasCost,
[Opcode.SUB]: DefaultBaseGasCost,
[Opcode.MUL]: DefaultBaseGasCost,
[Opcode.DIV]: DefaultBaseGasCost,
[Opcode.FDIV]: DefaultBaseGasCost,
[Opcode.EQ]: DefaultBaseGasCost,
[Opcode.LT]: DefaultBaseGasCost,
[Opcode.LTE]: DefaultBaseGasCost,
[Opcode.AND]: DefaultBaseGasCost,
[Opcode.OR]: DefaultBaseGasCost,
[Opcode.XOR]: DefaultBaseGasCost,
[Opcode.NOT]: DefaultBaseGasCost,
[Opcode.SHL]: DefaultBaseGasCost,
[Opcode.SHR]: DefaultBaseGasCost,
[Opcode.CAST]: DefaultBaseGasCost,
// Execution environment
[Opcode.ADDRESS]: TemporaryDefaultGasCost,
[Opcode.STORAGEADDRESS]: TemporaryDefaultGasCost,
[Opcode.SENDER]: TemporaryDefaultGasCost,
[Opcode.FEEPERL2GAS]: TemporaryDefaultGasCost,
[Opcode.FEEPERDAGAS]: TemporaryDefaultGasCost,
[Opcode.TRANSACTIONFEE]: TemporaryDefaultGasCost,
[Opcode.CONTRACTCALLDEPTH]: TemporaryDefaultGasCost,
[Opcode.CHAINID]: TemporaryDefaultGasCost,
[Opcode.VERSION]: TemporaryDefaultGasCost,
[Opcode.BLOCKNUMBER]: TemporaryDefaultGasCost,
[Opcode.TIMESTAMP]: TemporaryDefaultGasCost,
[Opcode.COINBASE]: TemporaryDefaultGasCost,
[Opcode.BLOCKL2GASLIMIT]: TemporaryDefaultGasCost,
[Opcode.BLOCKDAGASLIMIT]: TemporaryDefaultGasCost,
[Opcode.CALLDATACOPY]: TemporaryDefaultGasCost,
[Opcode.ADDRESS]: DefaultBaseGasCost,
[Opcode.STORAGEADDRESS]: DefaultBaseGasCost,
[Opcode.SENDER]: DefaultBaseGasCost,
[Opcode.FEEPERL2GAS]: DefaultBaseGasCost,
[Opcode.FEEPERDAGAS]: DefaultBaseGasCost,
[Opcode.TRANSACTIONFEE]: DefaultBaseGasCost,
[Opcode.CONTRACTCALLDEPTH]: DefaultBaseGasCost,
[Opcode.CHAINID]: DefaultBaseGasCost,
[Opcode.VERSION]: DefaultBaseGasCost,
[Opcode.BLOCKNUMBER]: DefaultBaseGasCost,
[Opcode.TIMESTAMP]: DefaultBaseGasCost,
[Opcode.COINBASE]: DefaultBaseGasCost,
[Opcode.BLOCKL2GASLIMIT]: DefaultBaseGasCost,
[Opcode.BLOCKDAGASLIMIT]: DefaultBaseGasCost,
[Opcode.CALLDATACOPY]: DefaultBaseGasCost,
// Gas
[Opcode.L2GASLEFT]: TemporaryDefaultGasCost,
[Opcode.DAGASLEFT]: TemporaryDefaultGasCost,
[Opcode.L2GASLEFT]: DefaultBaseGasCost,
[Opcode.DAGASLEFT]: DefaultBaseGasCost,
// Control flow
[Opcode.JUMP]: TemporaryDefaultGasCost,
[Opcode.JUMPI]: TemporaryDefaultGasCost,
[Opcode.INTERNALCALL]: TemporaryDefaultGasCost,
[Opcode.INTERNALRETURN]: TemporaryDefaultGasCost,
[Opcode.JUMP]: DefaultBaseGasCost,
[Opcode.JUMPI]: DefaultBaseGasCost,
[Opcode.INTERNALCALL]: DefaultBaseGasCost,
[Opcode.INTERNALRETURN]: DefaultBaseGasCost,
// Memory
[Opcode.SET]: TemporaryDefaultGasCost,
[Opcode.MOV]: TemporaryDefaultGasCost,
[Opcode.CMOV]: TemporaryDefaultGasCost,
[Opcode.SET]: DefaultBaseGasCost,
[Opcode.MOV]: DefaultBaseGasCost,
[Opcode.CMOV]: DefaultBaseGasCost,
// World state
[Opcode.SLOAD]: TemporaryDefaultGasCost,
[Opcode.SSTORE]: TemporaryDefaultGasCost,
[Opcode.NOTEHASHEXISTS]: TemporaryDefaultGasCost,
[Opcode.EMITNOTEHASH]: TemporaryDefaultGasCost,
[Opcode.NULLIFIEREXISTS]: TemporaryDefaultGasCost,
[Opcode.EMITNULLIFIER]: TemporaryDefaultGasCost,
[Opcode.L1TOL2MSGEXISTS]: TemporaryDefaultGasCost,
[Opcode.HEADERMEMBER]: TemporaryDefaultGasCost,
[Opcode.EMITUNENCRYPTEDLOG]: TemporaryDefaultGasCost,
[Opcode.SENDL2TOL1MSG]: TemporaryDefaultGasCost,
[Opcode.GETCONTRACTINSTANCE]: TemporaryDefaultGasCost,
[Opcode.SLOAD]: DefaultBaseGasCost,
[Opcode.SSTORE]: DefaultBaseGasCost,
[Opcode.NOTEHASHEXISTS]: DefaultBaseGasCost,
[Opcode.EMITNOTEHASH]: DefaultBaseGasCost,
[Opcode.NULLIFIEREXISTS]: DefaultBaseGasCost,
[Opcode.EMITNULLIFIER]: DefaultBaseGasCost,
[Opcode.L1TOL2MSGEXISTS]: DefaultBaseGasCost,
[Opcode.HEADERMEMBER]: DefaultBaseGasCost,
[Opcode.EMITUNENCRYPTEDLOG]: DefaultBaseGasCost,
[Opcode.SENDL2TOL1MSG]: DefaultBaseGasCost,
[Opcode.GETCONTRACTINSTANCE]: DefaultBaseGasCost,
// External calls
[Opcode.CALL]: TemporaryDefaultGasCost,
[Opcode.STATICCALL]: TemporaryDefaultGasCost,
[Opcode.DELEGATECALL]: TemporaryDefaultGasCost,
[Opcode.RETURN]: TemporaryDefaultGasCost,
[Opcode.REVERT]: TemporaryDefaultGasCost,
[Opcode.CALL]: DefaultBaseGasCost,
[Opcode.STATICCALL]: DefaultBaseGasCost,
[Opcode.DELEGATECALL]: DefaultBaseGasCost,
[Opcode.RETURN]: DefaultBaseGasCost,
[Opcode.REVERT]: DefaultBaseGasCost,
// Misc
[Opcode.DEBUGLOG]: TemporaryDefaultGasCost,
[Opcode.DEBUGLOG]: DefaultBaseGasCost,
// Gadgets
[Opcode.KECCAK]: TemporaryDefaultGasCost,
[Opcode.POSEIDON2]: TemporaryDefaultGasCost,
[Opcode.SHA256]: TemporaryDefaultGasCost, // temp - may be removed, but alot of contracts rely on i: TemporaryDefaultGasCost,
[Opcode.PEDERSEN]: TemporaryDefaultGasCost, // temp - may be removed, but alot of contracts rely on i: TemporaryDefaultGasCost,t
[Opcode.KECCAK]: DefaultBaseGasCost,
[Opcode.POSEIDON2]: DefaultBaseGasCost,
[Opcode.SHA256]: DefaultBaseGasCost,
[Opcode.PEDERSEN]: DefaultBaseGasCost,
// Conversions
[Opcode.TORADIXLE]: TemporaryDefaultGasCost,
[Opcode.TORADIXLE]: DefaultBaseGasCost,
};

/** Returns the fixed base gas cost for a given opcode, or throws if set to dynamic. */
/** Returns the fixed base gas cost for a given opcode. */
export function getBaseGasCost(opcode: Opcode): Gas {
const cost = GasCosts[opcode];
if (cost === DynamicGasCost) {
throw new Error(`Opcode ${Opcode[opcode]} has dynamic gas cost`);
}
return cost;
return BaseGasCosts[opcode];
}

/** Returns the gas cost associated with the memory operations performed. */
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 @@ -50,7 +50,7 @@ describe('AVM simulator: injected bytecode', () => {

expect(results.reverted).toBe(false);
expect(results.output).toEqual([new Fr(3)]);
expect(context.machineState.l2GasLeft).toEqual(initialL2GasLeft - 670);
expect(context.machineState.l2GasLeft).toEqual(initialL2GasLeft - 30);
});

it('Should halt if runs out of gas', async () => {
Expand Down
15 changes: 1 addition & 14 deletions yarn-project/simulator/src/avm/opcodes/arithmetic.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { AvmContext } from '../avm_context.js';
import { getBaseGasCost, getGasCostForTypeTag, getMemoryGasCost, sumGas } from '../avm_gas.js';
import { type Field, type MemoryOperations, type MemoryValue, TypeTag } from '../avm_memory_types.js';
import { type Field, type MemoryValue, TypeTag } from '../avm_memory_types.js';
import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
import { Instruction } from './instruction.js';
import { ThreeOperandInstruction } from './instruction_impl.js';
Expand All @@ -23,12 +22,6 @@ export abstract class ThreeOperandArithmeticInstruction extends ThreeOperandInst
context.machineState.incrementPc();
}

protected override gasCost(memoryOps: Partial<MemoryOperations & { indirect: number }>) {
const baseGasCost = getGasCostForTypeTag(this.inTag, getBaseGasCost(this.opcode));
const memoryGasCost = getMemoryGasCost(memoryOps);
return sumGas(baseGasCost, memoryGasCost);
}

protected abstract compute(a: MemoryValue, b: MemoryValue): MemoryValue;
}

Expand Down Expand Up @@ -101,10 +94,4 @@ export class FieldDiv extends Instruction {
memory.assert(memoryOperations);
context.machineState.incrementPc();
}

protected override gasCost(memoryOps: Partial<MemoryOperations & { indirect: number }>) {
const baseGasCost = getGasCostForTypeTag(TypeTag.FIELD, getBaseGasCost(this.opcode));
const memoryGasCost = getMemoryGasCost(memoryOps);
return sumGas(baseGasCost, memoryGasCost);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ describe.each([
await instruction.execute(context);

const actual = context.machineState.memory.get(0).toNumber();
const expected = key === 'l2GasLeft' ? value - 110 : value; // l2gascost decreases when it's executed
const expected = key === 'l2GasLeft' ? value - 10 : value; // l2gascost decreases when it's executed
expect(actual).toEqual(expected);
});
});
8 changes: 5 additions & 3 deletions yarn-project/simulator/src/avm/opcodes/instruction.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { strict as assert } from 'assert';

import type { AvmContext } from '../avm_context.js';
import { getBaseGasCost, getMemoryGasCost, sumGas } from '../avm_gas.js';
import { getBaseGasCost, sumGas } from '../avm_gas.js';
import { type MemoryOperations } from '../avm_memory_types.js';
import { type BufferCursor } from '../serialization/buffer_cursor.js';
import { Opcode, type OperandType, deserialize, serialize } from '../serialization/instruction_serialization.js';
Expand Down Expand Up @@ -67,9 +67,11 @@ export abstract class Instruction {
* @param memoryOps Memory operations performed by the instruction.
* @returns Gas cost.
*/
protected gasCost(memoryOps: Partial<MemoryOperations & { indirect: number }> = {}) {
protected gasCost(_memoryOps: Partial<MemoryOperations & { indirect: number }> = {}) {
const baseGasCost = getBaseGasCost(this.opcode);
const memoryGasCost = getMemoryGasCost(memoryOps);
// TODO(https://github.com/AztecProtocol/aztec-packages/issues/6861): reconsider.
// const memoryGasCost = getMemoryGasCost(memoryOps);
const memoryGasCost = { l2Gas: 0, daGas: 0 };
return sumGas(baseGasCost, memoryGasCost);
}

Expand Down
9 changes: 1 addition & 8 deletions yarn-project/simulator/src/avm/opcodes/memory.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { AvmContext } from '../avm_context.js';
import { getBaseGasCost, getMemoryGasCost, sumGas } from '../avm_gas.js';
import { Field, type MemoryOperations, TaggedMemory, TypeTag } from '../avm_memory_types.js';
import { Field, TaggedMemory, TypeTag } from '../avm_memory_types.js';
import { InstructionExecutionError } from '../errors.js';
import { BufferCursor } from '../serialization/buffer_cursor.js';
import { Opcode, OperandType, deserialize, serialize } from '../serialization/instruction_serialization.js';
Expand Down Expand Up @@ -216,10 +215,4 @@ export class CalldataCopy extends Instruction {
memory.assert(memoryOperations);
context.machineState.incrementPc();
}

protected override gasCost(memoryOps: Partial<MemoryOperations & { indirect: number }> = {}) {
const baseGasCost = getBaseGasCost(this.opcode);
const memoryGasCost = getMemoryGasCost(memoryOps);
return sumGas(baseGasCost, memoryGasCost);
}
}
9 changes: 1 addition & 8 deletions yarn-project/simulator/src/avm/opcodes/storage.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { Fr } from '@aztec/foundation/fields';

import type { AvmContext } from '../avm_context.js';
import { type Gas, getBaseGasCost, getMemoryGasCost, mulGas, sumGas } from '../avm_gas.js';
import { Field, type MemoryOperations } from '../avm_memory_types.js';
import { Field } from '../avm_memory_types.js';
import { StaticCallAlterationError } from '../errors.js';
import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
import { Addressing } from './addressing_mode.js';
Expand All @@ -26,12 +25,6 @@ abstract class BaseStorageInstruction extends Instruction {
) {
super();
}

protected override gasCost(memoryOps: Partial<MemoryOperations & { indirect: number }>): Gas {
const baseGasCost = mulGas(getBaseGasCost(this.opcode), this.size);
const memoryGasCost = getMemoryGasCost(memoryOps);
return sumGas(baseGasCost, memoryGasCost);
}
}

export class SStore extends BaseStorageInstruction {
Expand Down

0 comments on commit 12b1b0e

Please sign in to comment.