Skip to content

Commit

Permalink
Merge 26fdb8b into 276a82c
Browse files Browse the repository at this point in the history
  • Loading branch information
dbanks12 authored Dec 11, 2024
2 parents 276a82c + 26fdb8b commit 99262a4
Show file tree
Hide file tree
Showing 14 changed files with 72 additions and 91 deletions.
21 changes: 0 additions & 21 deletions barretenberg/cpp/src/barretenberg/vm/avm/tests/execution.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1739,27 +1739,6 @@ TEST_F(AvmExecutionTests, daGasLeft)
validate_trace(std::move(trace), public_inputs);
}

TEST_F(AvmExecutionTests, ExecutorThrowsWithTooMuchGasAllocated)
{
GTEST_SKIP();
std::string bytecode_hex = to_hex(OpCode::GETENVVAR_16) + // opcode GETENVVAR_16(sender)
"00" // Indirect flag
+ "0007" + to_hex(static_cast<uint8_t>(EnvironmentVariable::SENDER)); // addr 7

std::vector<FF> calldata = {};
std::vector<FF> returndata = {};
public_inputs.gas_settings.gas_limits.l2_gas = MAX_L2_GAS_PER_ENQUEUED_CALL;

auto bytecode = hex_to_bytes(bytecode_hex);
auto [instructions, error] = Deserialization::parse_bytecode_statically(bytecode);
ASSERT_TRUE(is_ok(error));

ExecutionHints execution_hints;
EXPECT_THROW_WITH_MESSAGE(gen_trace(bytecode, calldata, public_inputs, returndata, execution_hints),
"Cannot allocate more than MAX_L2_GAS_PER_ENQUEUED_CALL to the AVM for "
"execution of an enqueued call");
}

// Should throw whenever the wrong number of public inputs are provided
// TEST_F(AvmExecutionTests, ExecutorThrowsWithIncorrectNumberOfPublicInputs)
// {
Expand Down
15 changes: 0 additions & 15 deletions barretenberg/cpp/src/barretenberg/vm/avm/trace/helper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,6 @@ template <typename FF_> VmPublicInputs_<FF_> convert_public_inputs(std::vector<F
throw_or_abort("Public inputs vector is not of PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH");
}

// WARNING: this must be constrained by the kernel!
// Here this is just a sanity check to prevent generation of proofs that
// will be thrown out by the kernel anyway.
if constexpr (IsAnyOf<FF_, bb::fr>) {
if (public_inputs_vec[L2_START_GAS_LEFT_PCPI_OFFSET] > MAX_L2_GAS_PER_ENQUEUED_CALL) {
throw_or_abort(
"Cannot allocate more than MAX_L2_GAS_PER_ENQUEUED_CALL to the AVM for execution of an enqueued call");
}
} else {
if (public_inputs_vec[L2_START_GAS_LEFT_PCPI_OFFSET].get_value() > MAX_L2_GAS_PER_ENQUEUED_CALL) {
throw_or_abort(
"Cannot allocate more than MAX_L2_GAS_PER_ENQUEUED_CALL to the AVM for execution of an enqueued call");
}
}

std::array<FF_, KERNEL_INPUTS_LENGTH>& kernel_inputs = std::get<KERNEL_INPUTS>(public_inputs);

// Copy items from PublicCircuitPublicInputs vector to public input columns
Expand Down
9 changes: 8 additions & 1 deletion barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -401,9 +401,16 @@ AvmTraceBuilder::AvmTraceBuilder(AvmPublicInputs public_inputs,
, bytecode_trace_builder(execution_hints.all_contract_bytecode)
, merkle_tree_trace_builder(public_inputs.start_tree_snapshots)
{
// Only allocate up to the maximum L2 gas for execution
// TODO: constrain this!
auto const l2_gas_left_after_private =
public_inputs.gas_settings.gas_limits.l2_gas - public_inputs.start_gas_used.l2_gas;
// TODO: think about cast
auto const allocated_l2_gas =
std::min(l2_gas_left_after_private, static_cast<uint32_t>(MAX_L2_GAS_PER_TX_PUBLIC_PORTION));
// TODO: think about cast
gas_trace_builder.set_initial_gas(
static_cast<uint32_t>(public_inputs.gas_settings.gas_limits.l2_gas - public_inputs.start_gas_used.l2_gas),
static_cast<uint32_t>(allocated_l2_gas),
static_cast<uint32_t>(public_inputs.gas_settings.gas_limits.da_gas - public_inputs.start_gas_used.da_gas));
}

Expand Down
2 changes: 1 addition & 1 deletion barretenberg/cpp/src/barretenberg/vm/aztec_constants.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#define MAX_L2_TO_L1_MSGS_PER_TX 8
#define MAX_UNENCRYPTED_LOGS_PER_TX 8
#define MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS 3000
#define MAX_L2_GAS_PER_ENQUEUED_CALL 12000000
#define MAX_L2_GAS_PER_TX_PUBLIC_PORTION 12000000
#define CANONICAL_AUTH_REGISTRY_ADDRESS 1
#define DEPLOYER_CONTRACT_ADDRESS 2
#define REGISTERER_CONTRACT_ADDRESS 3
Expand Down
4 changes: 4 additions & 0 deletions docs/docs/migration_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ Further changes are planned, so that:

## 0.66

### L2 Gas limit of 12M enforced for public portion of TX

This limit was previously enforced per-enqueued-public-call. The protocol now enforces a stricter limit that the entire public portion of a transaction consumes at most 12,000,000 L2 gas.

### DEBUG env var is removed

The `DEBUG` variable is no longer used. Use `LOG_LEVEL` with one of `silent`, `fatal`, `error`, `warn`, `info`, `verbose`, `debug`, or `trace`. To tweak log levels per module, add a list of module prefixes with their overridden level. For example, LOG_LEVEL="info; verbose: aztec:sequencer, aztec:archiver; debug: aztec:kv-store" sets `info` as the default log level, `verbose` for the sequencer and archiver, and `debug` for the kv-store. Module name match is done by prefix.
Expand Down
4 changes: 2 additions & 2 deletions l1-contracts/src/core/libraries/ConstantsGen.sol
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,12 @@ library Constants {
14061769416655647708490531650437236735160113654556896985372298487345;
uint256 internal constant DEFAULT_GAS_LIMIT = 1000000000;
uint256 internal constant DEFAULT_TEARDOWN_GAS_LIMIT = 12000000;
uint256 internal constant MAX_L2_GAS_PER_ENQUEUED_CALL = 12000000;
uint256 internal constant MAX_L2_GAS_PER_TX_PUBLIC_PORTION = 12000000;
uint256 internal constant DA_BYTES_PER_FIELD = 32;
uint256 internal constant DA_GAS_PER_BYTE = 16;
uint256 internal constant FIXED_DA_GAS = 512;
uint256 internal constant FIXED_L2_GAS = 512;
uint256 internal constant FIXED_AVM_STARTUP_L2_GAS = 1024;
uint256 internal constant FIXED_AVM_STARTUP_L2_GAS = 20000;
uint256 internal constant L2_GAS_DISTRIBUTED_STORAGE_PREMIUM = 1024;
uint256 internal constant L2_GAS_PER_READ_MERKLE_HASH = 30;
uint256 internal constant L2_GAS_PER_WRITE_MERKLE_HASH = 40;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,15 +171,15 @@ pub global DEPLOYER_CONTRACT_INSTANCE_DEPLOYED_MAGIC_VALUE: Field =
// GAS DEFAULTS
pub global DEFAULT_GAS_LIMIT: u32 = 1_000_000_000;
pub global DEFAULT_TEARDOWN_GAS_LIMIT: u32 = 12_000_000;
pub global MAX_L2_GAS_PER_ENQUEUED_CALL: u32 = 12_000_000;
pub global MAX_L2_GAS_PER_TX_PUBLIC_PORTION: u32 = 12_000_000;
pub global DA_BYTES_PER_FIELD: u32 = 32;
pub global DA_GAS_PER_BYTE: u32 = 16;
// pays for preamble information in TX Effects
pub global FIXED_DA_GAS: u32 = 512;
// pays for fixed tx costs like validation, and updating state roots
pub global FIXED_L2_GAS: u32 = 512;
// base cost for a single public call
pub global FIXED_AVM_STARTUP_L2_GAS: u32 = 1024;
pub global FIXED_AVM_STARTUP_L2_GAS: u32 = 20_000;

// Some tree insertions incur an additional cost associated with
// the new database entry to be stored by all network participants.
Expand Down
4 changes: 2 additions & 2 deletions yarn-project/circuits.js/src/constants.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,12 @@ export const DEPLOYER_CONTRACT_INSTANCE_DEPLOYED_MAGIC_VALUE =
14061769416655647708490531650437236735160113654556896985372298487345n;
export const DEFAULT_GAS_LIMIT = 1000000000;
export const DEFAULT_TEARDOWN_GAS_LIMIT = 12000000;
export const MAX_L2_GAS_PER_ENQUEUED_CALL = 12000000;
export const MAX_L2_GAS_PER_TX_PUBLIC_PORTION = 12000000;
export const DA_BYTES_PER_FIELD = 32;
export const DA_GAS_PER_BYTE = 16;
export const FIXED_DA_GAS = 512;
export const FIXED_L2_GAS = 512;
export const FIXED_AVM_STARTUP_L2_GAS = 1024;
export const FIXED_AVM_STARTUP_L2_GAS = 20000;
export const L2_GAS_DISTRIBUTED_STORAGE_PREMIUM = 1024;
export const L2_GAS_PER_READ_MERKLE_HASH = 30;
export const L2_GAS_PER_WRITE_MERKLE_HASH = 40;
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/circuits.js/src/scripts/constants.in.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ const CPP_CONSTANTS = [
'MEM_TAG_U64',
'MEM_TAG_U128',
'MEM_TAG_FF',
'MAX_L2_GAS_PER_ENQUEUED_CALL',
'MAX_L2_GAS_PER_TX_PUBLIC_PORTION',
'MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS',
'CANONICAL_AUTH_REGISTRY_ADDRESS',
'DEPLOYER_CONTRACT_ADDRESS',
Expand Down
6 changes: 3 additions & 3 deletions yarn-project/simulator/src/avm/avm_simulator.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type AztecAddress, Fr, type GlobalVariables, MAX_L2_GAS_PER_ENQUEUED_CALL } from '@aztec/circuits.js';
import { type AztecAddress, Fr, type GlobalVariables, MAX_L2_GAS_PER_TX_PUBLIC_PORTION } from '@aztec/circuits.js';
import { type Logger, createLogger } from '@aztec/foundation/log';

import { strict as assert } from 'assert';
Expand Down Expand Up @@ -47,8 +47,8 @@ export class AvmSimulator {
// only. Otherwise, use build() below.
constructor(private context: AvmContext, private instructionSet: InstructionSet = INSTRUCTION_SET()) {
assert(
context.machineState.gasLeft.l2Gas <= MAX_L2_GAS_PER_ENQUEUED_CALL,
`Cannot allocate more than ${MAX_L2_GAS_PER_ENQUEUED_CALL} to the AVM for execution of an enqueued call`,
context.machineState.gasLeft.l2Gas <= MAX_L2_GAS_PER_TX_PUBLIC_PORTION,
`Cannot allocate more than ${MAX_L2_GAS_PER_TX_PUBLIC_PORTION} to the AVM for execution.`,
);
this.log = createLogger(`simulator:avm(calldata[0]: ${context.environment.calldata[0]})`);
// TODO(palla/log): Should tallies be printed on debug, or only on trace?
Expand Down
4 changes: 2 additions & 2 deletions yarn-project/simulator/src/avm/fixtures/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { isNoirCallStackUnresolved } from '@aztec/circuit-types';
import { GasFees, GlobalVariables, MAX_L2_GAS_PER_ENQUEUED_CALL } from '@aztec/circuits.js';
import { GasFees, GlobalVariables, MAX_L2_GAS_PER_TX_PUBLIC_PORTION } from '@aztec/circuits.js';
import { type FunctionArtifact, FunctionSelector } from '@aztec/foundation/abi';
import { AztecAddress } from '@aztec/foundation/aztec-address';
import { EthAddress } from '@aztec/foundation/eth-address';
Expand Down Expand Up @@ -93,7 +93,7 @@ export function initGlobalVariables(overrides?: Partial<GlobalVariables>): Globa
*/
export function initMachineState(overrides?: Partial<AvmMachineState>): AvmMachineState {
return AvmMachineState.fromState({
l2GasLeft: overrides?.l2GasLeft ?? MAX_L2_GAS_PER_ENQUEUED_CALL,
l2GasLeft: overrides?.l2GasLeft ?? MAX_L2_GAS_PER_TX_PUBLIC_PORTION,
daGasLeft: overrides?.daGasLeft ?? 1e8,
});
}
Expand Down
4 changes: 2 additions & 2 deletions yarn-project/simulator/src/public/fixtures/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
GasFees,
GasSettings,
GlobalVariables,
MAX_L2_GAS_PER_ENQUEUED_CALL,
MAX_L2_GAS_PER_TX_PUBLIC_PORTION,
PartialPrivateTailPublicInputsForPublic,
PrivateKernelTailCircuitPublicInputs,
type PublicFunction,
Expand Down Expand Up @@ -113,7 +113,7 @@ export function createTxForPublicCall(
): Tx {
const callRequest = executionRequest.toCallRequest();
// use max limits
const gasLimits = new Gas(DEFAULT_GAS_LIMIT, MAX_L2_GAS_PER_ENQUEUED_CALL);
const gasLimits = new Gas(DEFAULT_GAS_LIMIT, MAX_L2_GAS_PER_TX_PUBLIC_PORTION);

const forPublic = PartialPrivateTailPublicInputsForPublic.empty();
// TODO(#9269): Remove this fake nullifier method as we move away from 1st nullifier as hash.
Expand Down
63 changes: 41 additions & 22 deletions yarn-project/simulator/src/public/public_tx_context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
Gas,
type GasSettings,
type GlobalVariables,
MAX_L2_GAS_PER_TX_PUBLIC_PORTION,
type PrivateToPublicAccumulatedData,
type PublicCallRequest,
PublicCircuitPublicInputs,
Expand All @@ -43,7 +44,7 @@ export class PublicTxContext {
private log: Logger;

/* Gas used including private, teardown gas _limit_, setup and app logic */
private gasUsed: Gas;
private gasUsedByPublic: Gas = Gas.empty();
/* Gas actually used during teardown (different from limit) */
public teardownGasUsed: Gas = Gas.empty();

Expand All @@ -60,8 +61,9 @@ export class PublicTxContext {
public readonly state: PhaseStateManager,
private readonly globalVariables: GlobalVariables,
private readonly startStateReference: StateReference,
private readonly startGasUsed: Gas,
private readonly gasSettings: GasSettings,
private readonly gasUsedByPrivate: Gas,
private readonly gasAllocatedToPublic: Gas,
private readonly setupCallRequests: PublicCallRequest[],
private readonly appLogicCallRequests: PublicCallRequest[],
private readonly teardownCallRequests: PublicCallRequest[],
Expand All @@ -73,7 +75,6 @@ export class PublicTxContext {
public trace: PublicEnqueuedCallSideEffectTrace, // FIXME(dbanks12): should be private
) {
this.log = createLogger(`simulator:public_tx_context`);
this.gasUsed = startGasUsed;
}

public static async create(
Expand All @@ -100,12 +101,18 @@ export class PublicTxContext {
// Transaction level state manager that will be forked for revertible phases.
const txStateManager = await AvmPersistableStateManager.create(worldStateDB, enqueuedCallTrace, doMerkleOperations);

const gasSettings = tx.data.constants.txContext.gasSettings;
const gasUsedByPrivate = tx.data.gasUsed;
// Gas allocated to public is "whatever's left" after private, but with some max applied.
const gasAllocatedToPublic = applyMaxToAvailableGas(gasSettings.gasLimits.sub(gasUsedByPrivate));

return new PublicTxContext(
new PhaseStateManager(txStateManager),
globalVariables,
await db.getStateReference(),
tx.data.gasUsed,
tx.data.constants.txContext.gasSettings,
gasSettings,
gasUsedByPrivate,
gasAllocatedToPublic,
getCallRequestsByPhase(tx, TxExecutionPhase.SETUP),
getCallRequestsByPhase(tx, TxExecutionPhase.APP_LOGIC),
getCallRequestsByPhase(tx, TxExecutionPhase.TEARDOWN),
Expand Down Expand Up @@ -226,13 +233,14 @@ export class PublicTxContext {
}

/**
* How much gas is left for the specified phase?
* How much gas is left as of the specified phase?
*/
getGasLeftForPhase(phase: TxExecutionPhase): Gas {
getGasLeftAtPhase(phase: TxExecutionPhase): Gas {
if (phase === TxExecutionPhase.TEARDOWN) {
return this.gasSettings.teardownGasLimits;
return applyMaxToAvailableGas(this.gasSettings.teardownGasLimits);
} else {
return this.gasSettings.gasLimits.sub(this.gasUsed);
const gasLeftForPublic = this.gasAllocatedToPublic.sub(this.gasUsedByPublic);
return gasLeftForPublic;
}
}

Expand All @@ -243,10 +251,18 @@ export class PublicTxContext {
if (phase === TxExecutionPhase.TEARDOWN) {
this.teardownGasUsed = this.teardownGasUsed.add(gas);
} else {
this.gasUsed = this.gasUsed.add(gas);
this.gasUsedByPublic = this.gasUsedByPublic.add(gas);
}
}

/**
* The gasUsed by public and private,
* as if the entire teardown gas limit was consumed.
*/
getTotalGasUsed(): Gas {
return this.gasUsedByPrivate.add(this.gasUsedByPublic);
}

/**
* Compute the gas used using the actual gas used during teardown instead
* of the teardown gas limit.
Expand All @@ -257,14 +273,7 @@ export class PublicTxContext {
assert(this.halted, 'Can only compute actual gas used after tx execution ends');
const requireTeardown = this.teardownCallRequests.length > 0;
const teardownGasLimits = requireTeardown ? this.gasSettings.teardownGasLimits : Gas.empty();
return this.gasUsed.sub(teardownGasLimits).add(this.teardownGasUsed);
}

/**
* The gasUsed as if the entire teardown gas limit was consumed.
*/
getGasUsedForFee(): Gas {
return this.gasUsed;
return this.getTotalGasUsed().sub(teardownGasLimits).add(this.teardownGasUsed);
}

/**
Expand All @@ -284,10 +293,10 @@ export class PublicTxContext {
* Should only be called during or after teardown.
*/
private getTransactionFeeUnsafe(): Fr {
const txFee = this.gasUsed.computeFee(this.globalVariables.gasFees);
const txFee = this.getTotalGasUsed().computeFee(this.globalVariables.gasFees);
this.log.debug(`Computed tx fee`, {
txFee,
gasUsed: inspect(this.gasUsed),
gasUsed: inspect(this.getTotalGasUsed()),
gasFees: inspect(this.globalVariables.gasFees),
});
return txFee;
Expand Down Expand Up @@ -320,15 +329,15 @@ export class PublicTxContext {
this.trace,
this.globalVariables,
this.startStateReference,
this.startGasUsed,
/*startGasUsed=*/ this.gasUsedByPrivate,
this.gasSettings,
this.setupCallRequests,
this.appLogicCallRequests,
this.teardownCallRequests,
this.nonRevertibleAccumulatedDataFromPrivate,
this.revertibleAccumulatedDataFromPrivate,
endTreeSnapshots,
/*endGasUsed=*/ this.gasUsed,
/*endGasUsed=*/ this.getTotalGasUsed(),
this.getTransactionFeeUnsafe(),
this.revertCode,
);
Expand Down Expand Up @@ -401,3 +410,13 @@ class PhaseStateManager {
this.currentlyActiveStateManager = undefined;
}
}

/**
* Apply L2 gas maximum.
*/
function applyMaxToAvailableGas(availableGas: Gas) {
return new Gas(
/*daGas=*/ availableGas.daGas,
/*l2Gas=*/ Math.min(availableGas.l2Gas, MAX_L2_GAS_PER_TX_PUBLIC_PORTION),
);
}
21 changes: 4 additions & 17 deletions yarn-project/simulator/src/public/public_tx_simulator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,7 @@ import {
UnencryptedFunctionL2Logs,
} from '@aztec/circuit-types';
import { type AvmSimulationStats } from '@aztec/circuit-types/stats';
import {
type Fr,
Gas,
type GlobalVariables,
MAX_L2_GAS_PER_ENQUEUED_CALL,
type PublicCallRequest,
type RevertCode,
} from '@aztec/circuits.js';
import { type Fr, type Gas, type GlobalVariables, type PublicCallRequest, type RevertCode } from '@aztec/circuits.js';
import { type Logger, createLogger } from '@aztec/foundation/log';
import { Timer } from '@aztec/foundation/timer';
import { Attributes, type TelemetryClient, type Tracer, trackSpan } from '@aztec/telemetry-client';
Expand Down Expand Up @@ -266,23 +259,17 @@ export class PublicTxSimulator {
const address = executionRequest.callContext.contractAddress;
const fnName = await getPublicFunctionDebugName(this.worldStateDB, address, executionRequest.args);

const availableGas = context.getGasLeftForPhase(phase);
// Gas allocated to an enqueued call can be different from the available gas
// if there is more gas available than the max allocation per enqueued call.
const allocatedGas = new Gas(
/*daGas=*/ availableGas.daGas,
/*l2Gas=*/ Math.min(availableGas.l2Gas, MAX_L2_GAS_PER_ENQUEUED_CALL),
);
const allocatedGas = context.getGasLeftAtPhase(phase);

const result = await this.simulateEnqueuedCallInternal(
context.state.getActiveStateManager(),
executionRequest,
allocatedGas,
context.getTransactionFee(phase),
/*transactionFee=*/ context.getTransactionFee(phase),
fnName,
);

const gasUsed = allocatedGas.sub(result.gasLeft);
const gasUsed = allocatedGas.sub(result.gasLeft); // by enqueued call
context.consumeGas(phase, gasUsed);
this.log.verbose(
`[AVM] Enqueued public call consumed ${gasUsed.l2Gas} L2 gas ending with ${result.gasLeft.l2Gas} L2 gas left.`,
Expand Down

0 comments on commit 99262a4

Please sign in to comment.