diff --git a/docs/Earthfile b/docs/Earthfile index 17986c9ff00..ebd913f0124 100644 --- a/docs/Earthfile +++ b/docs/Earthfile @@ -47,7 +47,7 @@ deploy-preview: COPY --dir ../yarn-project/+scripts-prod/usr/src/yarn-project /usr/src COPY ./netlify.toml . COPY ./deploy_preview.sh . - RUN NETLIFY_AUTH_TOKEN=$NETLIFY_AUTH_TOKEN NETLIFY_SITE_ID=$NETLIFY_SITE_ID ./deploy_preview.sh $PR $AZTEC_BOT_COMMENTER_GITHUB_TOKEN + RUN NETLIFY_AUTH_TOKEN=$NETLIFY_AUTH_TOKEN NETLIFY_SITE_ID=$NETLIFY_SITE_ID ./deploy_preview.sh "$PR" "$AZTEC_BOT_COMMENTER_GITHUB_TOKEN" deploy-prod: BUILD ../yarn-project/+scripts-prod diff --git a/docs/deploy_preview.sh b/docs/deploy_preview.sh index 74091495fd0..af544278342 100755 --- a/docs/deploy_preview.sh +++ b/docs/deploy_preview.sh @@ -26,4 +26,6 @@ DOCS_PREVIEW_URL=$(echo "$DEPLOY_OUTPUT" | grep -E "https://.*aztec-docs-dev.net echo "Unique deploy URL: $DOCS_PREVIEW_URL" cd ../yarn-project/scripts -AZTEC_BOT_COMMENTER_GITHUB_TOKEN=$AZTEC_BOT_COMMENTER_GITHUB_TOKEN PR_NUMBER=$PR_NUMBER DOCS_PREVIEW_URL=$DOCS_PREVIEW_URL yarn docs-preview-comment +if [ -n "$PR_NUMBER" ] ; then + AZTEC_BOT_COMMENTER_GITHUB_TOKEN=$AZTEC_BOT_COMMENTER_GITHUB_TOKEN PR_NUMBER=$PR_NUMBER DOCS_PREVIEW_URL=$DOCS_PREVIEW_URL yarn docs-preview-comment +fi diff --git a/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr index cb2bd989254..93c07de02a2 100644 --- a/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr @@ -619,7 +619,7 @@ contract AvmTest { dep::aztec::oracle::debug_log::debug_log("pedersen_hash_with_index"); let _ = pedersen_hash_with_index(args_field); dep::aztec::oracle::debug_log::debug_log("test_get_contract_instance"); - test_get_contract_instance(context.this_address()); + test_get_contract_instance(AztecAddress::from_field(args_field[0])); dep::aztec::oracle::debug_log::debug_log("get_address"); let _ = get_address(); dep::aztec::oracle::debug_log::debug_log("get_sender"); diff --git a/yarn-project/bb-prover/src/avm_proving.test.ts b/yarn-project/bb-prover/src/avm_proving.test.ts index b5580a4d97f..3e0ae84cf22 100644 --- a/yarn-project/bb-prover/src/avm_proving.test.ts +++ b/yarn-project/bb-prover/src/avm_proving.test.ts @@ -10,19 +10,13 @@ import path from 'path'; import { type BBSuccess, BB_RESULT, generateAvmProof, verifyAvmProof } from './bb/execute.js'; import { extractAvmVkData } from './verification_key/verification_key_data.js'; -const TIMEOUT = 180_000; - describe('AVM WitGen, proof generation and verification', () => { - it( - 'Should prove and verify bulk_testing', - async () => { - await proveAndVerifyAvmTestContract( - 'bulk_testing', - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(x => new Fr(x)), - ); - }, - TIMEOUT, - ); + it('Should prove and verify bulk_testing', async () => { + await proveAndVerifyAvmTestContract( + 'bulk_testing', + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(x => new Fr(x)), + ); + }, 180_000); }); async function proveAndVerifyAvmTestContract(functionName: string, calldata: Fr[] = []) { diff --git a/yarn-project/circuits.js/src/contract/artifact_hash.test.ts b/yarn-project/circuits.js/src/contract/artifact_hash.test.ts index 070ca03ba9b..06f2bb682bf 100644 --- a/yarn-project/circuits.js/src/contract/artifact_hash.test.ts +++ b/yarn-project/circuits.js/src/contract/artifact_hash.test.ts @@ -7,7 +7,7 @@ import { readFileSync } from 'fs'; import { getPathToFixture, getTestContractArtifact } from '../tests/fixtures.js'; import { computeArtifactHash } from './artifact_hash.js'; -const TEST_CONTRACT_ARTIFACT_HASH = `"0x08f4e5d2a0be9dc5c31894f88aaa93d353918078cd7fdfbbc7818ec3f2268b77"`; +const TEST_CONTRACT_ARTIFACT_HASH = `"0x1d429080e986cf55e59203b4229063bf9b4d875e832fe56c5257303075110190"`; describe('ArtifactHash', () => { it('calculates the artifact hash', () => { @@ -30,8 +30,10 @@ describe('ArtifactHash', () => { it('calculates the test contract artifact hash multiple times to ensure deterministic hashing', () => { const testArtifact = getTestContractArtifact(); + const calculatedArtifactHash = computeArtifactHash(testArtifact).toString(); + expect(calculatedArtifactHash).toMatchInlineSnapshot(TEST_CONTRACT_ARTIFACT_HASH); for (let i = 0; i < 1000; i++) { - expect(computeArtifactHash(testArtifact).toString()).toMatchInlineSnapshot(TEST_CONTRACT_ARTIFACT_HASH); + expect(computeArtifactHash(testArtifact).toString()).toBe(calculatedArtifactHash); } }); diff --git a/yarn-project/end-to-end/scripts/e2e_test_config.yml b/yarn-project/end-to-end/scripts/e2e_test_config.yml index 4faa61cceb7..a09f5f5a568 100644 --- a/yarn-project/end-to-end/scripts/e2e_test_config.yml +++ b/yarn-project/end-to-end/scripts/e2e_test_config.yml @@ -84,7 +84,8 @@ tests: e2e_state_vars: {} e2e_static_calls: {} e2e_synching: {} - e2e_token_contract: {} + e2e_token_contract: + with_alerts: true e2e_p2p_gossip: test_path: 'e2e_p2p/gossip_network.test.ts' with_alerts: true diff --git a/yarn-project/end-to-end/src/e2e_token_contract/token_contract_test.ts b/yarn-project/end-to-end/src/e2e_token_contract/token_contract_test.ts index 711e3fa92d7..0eb7afb8b83 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/token_contract_test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/token_contract_test.ts @@ -14,7 +14,7 @@ import { import { mintTokensToPrivate } from '../fixtures/token_utils.js'; import { TokenSimulator } from '../simulators/token_simulator.js'; -const { E2E_DATA_PATH: dataPath } = process.env; +const { E2E_DATA_PATH: dataPath, METRICS_PORT: metricsPort } = process.env; export class TokenContractTest { static TOKEN_NAME = 'USDC'; @@ -30,7 +30,9 @@ export class TokenContractTest { constructor(testName: string) { this.logger = createDebugLogger(`aztec:e2e_token_contract:${testName}`); - this.snapshotManager = createSnapshotManager(`e2e_token_contract/${testName}`, dataPath); + this.snapshotManager = createSnapshotManager(`e2e_token_contract/${testName}`, dataPath, { + metricsPort: metricsPort ? parseInt(metricsPort) : undefined, + }); } /** diff --git a/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_public.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_public.test.ts index 0c92a459ad0..b0440880ecb 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_public.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_public.test.ts @@ -1,8 +1,23 @@ import { Fr } from '@aztec/aztec.js'; import { U128_UNDERFLOW_ERROR } from '../fixtures/fixtures.js'; +import { AlertChecker, type AlertConfig } from '../quality_of_service/alert_checker.js'; import { TokenContractTest } from './token_contract_test.js'; +const CHECK_ALERTS = process.env.CHECK_ALERTS === 'true'; + +const qosAlerts: AlertConfig[] = [ + { + // Dummy alert to check that the metric is being emitted. + // Separate benchmark tests will use dedicated machines with the published system requirements. + alert: 'publishing_mana_per_second', + expr: 'rate(aztec_public_executor_simulation_mana_per_second_per_second_sum[5m]) / rate(aztec_public_executor_simulation_mana_per_second_per_second_count[5m]) < 10', + for: '5m', + annotations: {}, + labels: {}, + }, +]; + describe('e2e_token_contract transfer public', () => { const t = new TokenContractTest('transfer_in_public'); let { asset, accounts, tokenSim, wallets, badAccount } = t; @@ -17,6 +32,10 @@ describe('e2e_token_contract transfer public', () => { afterAll(async () => { await t.teardown(); + if (CHECK_ALERTS) { + const alertChecker = new AlertChecker(t.logger); + await alertChecker.runAlertCheck(qosAlerts); + } }); afterEach(async () => { diff --git a/yarn-project/end-to-end/src/fixtures/snapshot_manager.ts b/yarn-project/end-to-end/src/fixtures/snapshot_manager.ts index 6f58a48dda6..488e7291bda 100644 --- a/yarn-project/end-to-end/src/fixtures/snapshot_manager.ts +++ b/yarn-project/end-to-end/src/fixtures/snapshot_manager.ts @@ -345,7 +345,7 @@ async function setupFromFresh( aztecNodeConfig.bbWorkingDirectory = bbConfig.bbWorkingDirectory; } - const telemetry = await getEndToEndTestTelemetryClient(opts.metricsPort, /*serviceName*/ 'basenode'); + const telemetry = await getEndToEndTestTelemetryClient(opts.metricsPort, /*serviceName*/ statePath); logger.verbose('Creating and synching an aztec node...'); const aztecNode = await AztecNodeService.createAndSync(aztecNodeConfig, { telemetry }); diff --git a/yarn-project/ivc-integration/src/avm_integration.test.ts b/yarn-project/ivc-integration/src/avm_integration.test.ts index 63ed8fbaa5b..31a14eac16c 100644 --- a/yarn-project/ivc-integration/src/avm_integration.test.ts +++ b/yarn-project/ivc-integration/src/avm_integration.test.ts @@ -12,7 +12,6 @@ import { BufferReader } from '@aztec/foundation/serialize'; import { type FixedLengthArray } from '@aztec/noir-protocol-circuits-types/types'; import { simulateAvmTestContractGenerateCircuitInputs } from '@aztec/simulator/public/fixtures'; -import { jest } from '@jest/globals'; import fs from 'fs/promises'; import { tmpdir } from 'node:os'; import os from 'os'; @@ -23,9 +22,6 @@ import { MockPublicBaseCircuit, witnessGenMockPublicBaseCircuit } from './index. // Auto-generated types from noir are not in camel case. /* eslint-disable camelcase */ - -jest.setTimeout(240_000); - const logger = createDebugLogger('aztec:avm-integration'); describe('AVM Integration', () => { @@ -120,7 +116,7 @@ describe('AVM Integration', () => { ); expect(verifyResult.status).toBe(BB_RESULT.SUCCESS); - }); + }, 240_000); }); async function proveAvmTestContract(functionName: string, calldata: Fr[] = []): Promise { diff --git a/yarn-project/simulator/src/public/executor_metrics.ts b/yarn-project/simulator/src/public/executor_metrics.ts index 4b648dfe4ef..17267f58b90 100644 --- a/yarn-project/simulator/src/public/executor_metrics.ts +++ b/yarn-project/simulator/src/public/executor_metrics.ts @@ -3,15 +3,20 @@ import { type Histogram, Metrics, type TelemetryClient, + type Tracer, type UpDownCounter, ValueType, + linearBuckets, } from '@aztec/telemetry-client'; export class ExecutorMetrics { + public readonly tracer: Tracer; private fnCount: UpDownCounter; private fnDuration: Histogram; + private manaPerSecond: Histogram; constructor(client: TelemetryClient, name = 'PublicExecutor') { + this.tracer = client.getTracer(name); const meter = client.getMeter(name); this.fnCount = meter.createUpDownCounter(Metrics.PUBLIC_EXECUTOR_SIMULATION_COUNT, { @@ -23,13 +28,30 @@ export class ExecutorMetrics { unit: 'ms', valueType: ValueType.INT, }); + + this.manaPerSecond = meter.createHistogram(Metrics.PUBLIC_EXECUTOR_SIMULATION_MANA_PER_SECOND, { + description: 'Mana used per second', + unit: 'mana/s', + valueType: ValueType.INT, + advice: { + explicitBucketBoundaries: linearBuckets(0, 10_000_000, 10), + }, + }); } - recordFunctionSimulation(durationMs: number) { + recordFunctionSimulation(durationMs: number, manaUsed: number, fnName: string) { this.fnCount.add(1, { [Attributes.OK]: true, + [Attributes.APP_CIRCUIT_NAME]: fnName, + [Attributes.MANA_USED]: manaUsed, }); this.fnDuration.record(Math.ceil(durationMs)); + if (durationMs > 0 && manaUsed > 0) { + const manaPerSecond = Math.round((manaUsed * 1000) / durationMs); + this.manaPerSecond.record(manaPerSecond, { + [Attributes.APP_CIRCUIT_NAME]: fnName, + }); + } } recordFunctionSimulationFailure() { diff --git a/yarn-project/simulator/src/public/fixtures/index.ts b/yarn-project/simulator/src/public/fixtures/index.ts index 9b40a3b51f6..d4c69bfd9ae 100644 --- a/yarn-project/simulator/src/public/fixtures/index.ts +++ b/yarn-project/simulator/src/public/fixtures/index.ts @@ -2,7 +2,10 @@ import { PublicExecutionRequest, Tx } from '@aztec/circuit-types'; import { type AvmCircuitInputs, CallContext, + type ContractClassPublic, + type ContractInstanceWithAddress, DEFAULT_GAS_LIMIT, + type FunctionSelector, Gas, GasFees, GasSettings, @@ -20,19 +23,16 @@ import { computePublicBytecodeCommitment, } from '@aztec/circuits.js'; import { makeContractClassPublic, makeContractInstanceFromClassId } from '@aztec/circuits.js/testing'; +import { type ContractArtifact } from '@aztec/foundation/abi'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr, Point } from '@aztec/foundation/fields'; import { openTmpStore } from '@aztec/kv-store/utils'; -import { PublicTxSimulator, type WorldStateDB } from '@aztec/simulator'; +import { PublicTxSimulator, WorldStateDB } from '@aztec/simulator'; import { NoopTelemetryClient } from '@aztec/telemetry-client/noop'; import { MerkleTrees } from '@aztec/world-state'; -import { mock } from 'jest-mock-extended'; - import { getAvmTestContractBytecode, getAvmTestContractFunctionSelector } from '../../avm/fixtures/index.js'; -const TIMESTAMP = new Fr(99833); - /** * If assertionErrString is set, we expect a (non exceptional halting) revert due to a failing assertion and * we check that the revert reason error contains this string. However, the circuit must correctly prove the @@ -49,46 +49,14 @@ export async function simulateAvmTestContractGenerateCircuitInputs( const globalVariables = GlobalVariables.empty(); globalVariables.gasFees = GasFees.empty(); - globalVariables.timestamp = TIMESTAMP; + globalVariables.timestamp = new Fr(99833); - const worldStateDB = mock(); const telemetry = new NoopTelemetryClient(); const merkleTrees = await (await MerkleTrees.new(openTmpStore(), telemetry)).fork(); - worldStateDB.getMerkleInterface.mockReturnValue(merkleTrees); - - // Top level contract call - const bytecode = getAvmTestContractBytecode('public_dispatch'); - const dispatchSelector = getAvmTestContractFunctionSelector('public_dispatch'); - const publicFn: PublicFunction = { bytecode, selector: dispatchSelector }; - const contractClass = makeContractClassPublic(0, publicFn); - const contractInstance = makeContractInstanceFromClassId(contractClass.id); - - // The values here should match those in `avm_simulator.test.ts` - const instanceGet = new SerializableContractInstance({ - version: 1, - salt: new Fr(0x123), - deployer: new AztecAddress(new Fr(0x456)), - contractClassId: new Fr(0x789), - initializationHash: new Fr(0x101112), - publicKeys: new PublicKeys( - new Point(new Fr(0x131415), new Fr(0x161718), false), - new Point(new Fr(0x192021), new Fr(0x222324), false), - new Point(new Fr(0x252627), new Fr(0x282930), false), - new Point(new Fr(0x313233), new Fr(0x343536), false), - ), - }).withAddress(contractInstance.address); - worldStateDB.getContractInstance - .mockResolvedValueOnce(contractInstance) - .mockResolvedValueOnce(instanceGet) // test gets deployer - .mockResolvedValueOnce(instanceGet) // test gets class id - .mockResolvedValueOnce(instanceGet) // test gets init hash - .mockResolvedValue(contractInstance); - worldStateDB.getContractClass.mockResolvedValue(contractClass); - worldStateDB.getBytecode.mockResolvedValue(bytecode); - worldStateDB.getBytecodeCommitment.mockResolvedValue(computePublicBytecodeCommitment(bytecode)); - - const storageValue = new Fr(5); - worldStateDB.storageRead.mockResolvedValue(Promise.resolve(storageValue)); + const contractDataSource = new MockedAvmTestContractDataSource(); + const worldStateDB = new WorldStateDB(merkleTrees, contractDataSource); + + const contractInstance = contractDataSource.contractInstance; const simulator = new PublicTxSimulator( merkleTrees, @@ -99,7 +67,12 @@ export async function simulateAvmTestContractGenerateCircuitInputs( /*doMerkleOperations=*/ true, ); - const callContext = new CallContext(sender, contractInstance.address, dispatchSelector, /*isStaticCall=*/ false); + const callContext = new CallContext( + sender, + contractInstance.address, + contractDataSource.fnSelector, + /*isStaticCall=*/ false, + ); const executionRequest = new PublicExecutionRequest(callContext, calldata); const tx: Tx = createTxForPublicCall(executionRequest); @@ -159,3 +132,81 @@ export function createTxForPublicCall( return tx; } + +class MockedAvmTestContractDataSource { + private fnName = 'public_dispatch'; + private bytecode: Buffer; + public fnSelector: FunctionSelector; + private publicFn: PublicFunction; + private contractClass: ContractClassPublic; + public contractInstance: ContractInstanceWithAddress; + private bytecodeCommitment: Fr; + private otherContractInstance: ContractInstanceWithAddress; + + constructor() { + this.bytecode = getAvmTestContractBytecode(this.fnName); + this.fnSelector = getAvmTestContractFunctionSelector(this.fnName); + this.publicFn = { bytecode: this.bytecode, selector: this.fnSelector }; + this.contractClass = makeContractClassPublic(0, this.publicFn); + this.contractInstance = makeContractInstanceFromClassId(this.contractClass.id); + this.bytecodeCommitment = computePublicBytecodeCommitment(this.bytecode); + // The values here should match those in `avm_simulator.test.ts` + this.otherContractInstance = new SerializableContractInstance({ + version: 1, + salt: new Fr(0x123), + deployer: new AztecAddress(new Fr(0x456)), + contractClassId: new Fr(0x789), + initializationHash: new Fr(0x101112), + publicKeys: new PublicKeys( + new Point(new Fr(0x131415), new Fr(0x161718), false), + new Point(new Fr(0x192021), new Fr(0x222324), false), + new Point(new Fr(0x252627), new Fr(0x282930), false), + new Point(new Fr(0x313233), new Fr(0x343536), false), + ), + }).withAddress(this.contractInstance.address); + } + + getPublicFunction(_address: AztecAddress, _selector: FunctionSelector): Promise { + return Promise.resolve(this.publicFn); + } + + getBlockNumber(): Promise { + throw new Error('Method not implemented.'); + } + + getContractClass(_id: Fr): Promise { + return Promise.resolve(this.contractClass); + } + + getBytecodeCommitment(_id: Fr): Promise { + return Promise.resolve(this.bytecodeCommitment); + } + + addContractClass(_contractClass: ContractClassPublic): Promise { + return Promise.resolve(); + } + + getContract(address: AztecAddress): Promise { + if (address.equals(this.contractInstance.address)) { + return Promise.resolve(this.contractInstance); + } else { + return Promise.resolve(this.otherContractInstance); + } + } + + getContractClassIds(): Promise { + throw new Error('Method not implemented.'); + } + + getContractArtifact(_address: AztecAddress): Promise { + throw new Error('Method not implemented.'); + } + + getContractFunctionName(_address: AztecAddress, _selector: FunctionSelector): Promise { + return Promise.resolve(this.fnName); + } + + addContractArtifact(_address: AztecAddress, _contract: ContractArtifact): Promise { + return Promise.resolve(); + } +} diff --git a/yarn-project/simulator/src/public/public_processor.ts b/yarn-project/simulator/src/public/public_processor.ts index f19c5d06973..23e33b9ee2f 100644 --- a/yarn-project/simulator/src/public/public_processor.ts +++ b/yarn-project/simulator/src/public/public_processor.ts @@ -229,6 +229,9 @@ export class PublicProcessor { return new PublicDataWrite(leafSlot, updatedBalance); } + @trackSpan('PublicProcessor.processPrivateOnlyTx', (tx: Tx) => ({ + [Attributes.TX_HASH]: tx.getTxHash().toString(), + })) private async processPrivateOnlyTx(tx: Tx): Promise<[ProcessedTx]> { const gasFees = this.globalVariables.gasFees; const transactionFee = tx.data.gasUsed.computeFee(gasFees); diff --git a/yarn-project/simulator/src/public/public_tx_simulator.test.ts b/yarn-project/simulator/src/public/public_tx_simulator.test.ts index 9e22910cca8..abd3f9e6671 100644 --- a/yarn-project/simulator/src/public/public_tx_simulator.test.ts +++ b/yarn-project/simulator/src/public/public_tx_simulator.test.ts @@ -204,7 +204,7 @@ describe('public_tx_simulator', () => { ); }, ); - }); + }, 30_000); afterEach(async () => { await treeStore.delete(); diff --git a/yarn-project/simulator/src/public/public_tx_simulator.ts b/yarn-project/simulator/src/public/public_tx_simulator.ts index 44801eff13f..37bf5245c42 100644 --- a/yarn-project/simulator/src/public/public_tx_simulator.ts +++ b/yarn-project/simulator/src/public/public_tx_simulator.ts @@ -20,7 +20,7 @@ import { } from '@aztec/circuits.js'; import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log'; import { Timer } from '@aztec/foundation/timer'; -import { type TelemetryClient } from '@aztec/telemetry-client'; +import { Attributes, type TelemetryClient, type Tracer, trackSpan } from '@aztec/telemetry-client'; import { type AvmFinalizedCallResult } from '../avm/avm_contract_call_result.js'; import { type AvmPersistableStateManager, AvmSimulator } from '../avm/index.js'; @@ -55,15 +55,18 @@ export class PublicTxSimulator { constructor( private db: MerkleTreeReadOperations, private worldStateDB: WorldStateDB, - client: TelemetryClient, + telemetryClient: TelemetryClient, private globalVariables: GlobalVariables, private realAvmProvingRequests: boolean = true, private doMerkleOperations: boolean = false, ) { this.log = createDebugLogger(`aztec:public_tx_simulator`); - this.metrics = new ExecutorMetrics(client, 'PublicTxSimulator'); + this.metrics = new ExecutorMetrics(telemetryClient, 'PublicTxSimulator'); } + get tracer(): Tracer { + return this.metrics.tracer; + } /** * Simulate a transaction's public portion including all of its phases. * @param tx - The transaction to simulate. @@ -244,6 +247,12 @@ export class PublicTxSimulator { * @param executionRequest - The execution request (includes args) * @returns The result of execution. */ + @trackSpan('PublicTxSimulator.simulateEnqueuedCall', (phase, context, _callRequest, executionRequest) => ({ + [Attributes.TX_HASH]: context.getTxHash().toString(), + [Attributes.TARGET_ADDRESS]: executionRequest.callContext.contractAddress.toString(), + [Attributes.SENDER_ADDRESS]: executionRequest.callContext.msgSender.toString(), + [Attributes.SIMULATOR_PHASE]: TxExecutionPhase[phase].toString(), + })) private async simulateEnqueuedCall( phase: TxExecutionPhase, context: PublicTxContext, @@ -312,6 +321,12 @@ export class PublicTxSimulator { * @param fnName - The name of the function * @returns The result of execution. */ + @trackSpan( + 'PublicTxSimulator.simulateEnqueuedCallInternal', + (_stateManager, _executionRequest, _allocatedGas, _transactionFee, fnName) => ({ + [Attributes.APP_CIRCUIT_NAME]: fnName, + }), + ) private async simulateEnqueuedCallInternal( stateManager: AvmPersistableStateManager, executionRequest: PublicExecutionRequest, @@ -356,7 +371,7 @@ export class PublicTxSimulator { if (result.reverted) { this.metrics.recordFunctionSimulationFailure(); } else { - this.metrics.recordFunctionSimulation(timer.ms()); + this.metrics.recordFunctionSimulation(timer.ms(), allocatedGas.sub(result.gasLeft).l2Gas, fnName); } return result; diff --git a/yarn-project/telemetry-client/src/attributes.ts b/yarn-project/telemetry-client/src/attributes.ts index 32ce263917a..87c4be24ce0 100644 --- a/yarn-project/telemetry-client/src/attributes.ts +++ b/yarn-project/telemetry-client/src/attributes.ts @@ -83,3 +83,8 @@ export const P2P_ID = 'aztec.p2p.id'; export const POOL_NAME = 'aztec.pool.name'; export const SEQUENCER_STATE = 'aztec.sequencer.state'; + +export const SIMULATOR_PHASE = 'aztec.simulator.phase'; +export const TARGET_ADDRESS = 'aztec.address.target'; +export const SENDER_ADDRESS = 'aztec.address.sender'; +export const MANA_USED = 'aztec.mana.used'; diff --git a/yarn-project/telemetry-client/src/metrics.ts b/yarn-project/telemetry-client/src/metrics.ts index f61e5be54ea..01f3e483497 100644 --- a/yarn-project/telemetry-client/src/metrics.ts +++ b/yarn-project/telemetry-client/src/metrics.ts @@ -71,6 +71,7 @@ export const PUBLIC_PROCESSOR_DEPLOY_BYTECODE_SIZE = 'aztec.public_processor.dep export const PUBLIC_EXECUTOR_SIMULATION_COUNT = 'aztec.public_executor.simulation_count'; export const PUBLIC_EXECUTOR_SIMULATION_DURATION = 'aztec.public_executor.simulation_duration'; +export const PUBLIC_EXECUTOR_SIMULATION_MANA_PER_SECOND = 'aztec.public_executor.simulation_mana_per_second'; export const PUBLIC_EXECUTION_SIMULATION_BYTECODE_SIZE = 'aztec.public_executor.simulation_bytecode_size'; export const PROVING_ORCHESTRATOR_BASE_ROLLUP_INPUTS_DURATION = diff --git a/yarn-project/telemetry-client/src/otel.ts b/yarn-project/telemetry-client/src/otel.ts index 446c50f0e89..f94d054cb31 100644 --- a/yarn-project/telemetry-client/src/otel.ts +++ b/yarn-project/telemetry-client/src/otel.ts @@ -75,7 +75,16 @@ export class OpenTelemetryClient implements TelemetryClient { } public async stop() { - await Promise.all([this.meterProvider.shutdown(), this.loggerProvider.shutdown()]); + const flushAndShutdown = async (provider: { forceFlush: () => Promise; shutdown: () => Promise }) => { + await provider.forceFlush(); + await provider.shutdown(); + }; + + await Promise.all([ + flushAndShutdown(this.meterProvider), + flushAndShutdown(this.loggerProvider), + this.traceProvider instanceof NodeTracerProvider ? flushAndShutdown(this.traceProvider) : Promise.resolve(), + ]); } public static async createAndStart(config: TelemetryClientConfig, log: DebugLogger): Promise { diff --git a/yarn-project/yarn.lock b/yarn-project/yarn.lock index f4f32a56c90..d80df020866 100644 --- a/yarn-project/yarn.lock +++ b/yarn-project/yarn.lock @@ -3522,6 +3522,7 @@ __metadata: "@noir-lang/acvm_js": 1.0.0-beta.0 "@noir-lang/noirc_abi": 1.0.0-beta.0 "@noir-lang/types": 1.0.0-beta.0 + checksum: 938fa6d909859abbc62eb45508b4a1729c3b3b0ced99dba2de37571697b9fa9f1c90c932e3768c01ceb50315e69d5c249e8a717e470f6fec33cf105a39b73cd4 languageName: node linkType: hard