Skip to content

Commit c391d68

Browse files
vezenovmaztec-bot
authored andcommitted
chore: bench public fns with emit repro (#23105)
Adds a bench for the contract shape from AztecProtocol/aztec-nr#35 (15 public fns each emitting an event). No existing bench target covers this flow. I want to see the benefits from follow-up improvements.
1 parent 64dcfcb commit c391d68

6 files changed

Lines changed: 1337 additions & 0 deletions

File tree

noir-projects/contract-snapshots/build.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ const EXPAND_CASES: &[(&str, &str)] = &[
3030
"avm_gadgets_test_contract",
3131
"../noir-contracts/contracts/test/avm_gadgets_test_contract",
3232
),
33+
(
34+
"public_fns_with_emit_repro_contract",
35+
"../noir-contracts/contracts/test/public_fns_with_emit_repro_contract",
36+
),
3337
];
3438

3539
fn main() {

noir-projects/contract-snapshots/tests/snapshots/expand/public_fns_with_emit_repro_contract/snapshots__expanded.snap

Lines changed: 1179 additions & 0 deletions
Large diffs are not rendered by default.

noir-projects/noir-contracts/Nargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ members = [
6666
"contracts/test/parent_contract",
6767
"contracts/test/pending_note_hashes_contract",
6868
"contracts/test/private_init_test_contract",
69+
"contracts/test/public_fns_with_emit_repro_contract",
6970
"contracts/test/public_immutable_contract",
7071
"contracts/test/returning_tuple_contract",
7172
"contracts/test/scope_test_contract",
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[package]
2+
name = "public_fns_with_emit_repro_contract"
3+
authors = [""]
4+
compiler_version = ">=0.25.0"
5+
type = "contract"
6+
7+
[dependencies]
8+
aztec = { path = "../../../../aztec-nr/aztec" }
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
use aztec::macros::aztec;
2+
3+
/// Bytecode-shape repro from https://github.com/AztecProtocol/aztec-nr/issues/35.
4+
///
5+
/// 15 `#[external("public")]` functions, each doing one storage read, one storage write,
6+
/// and one `self.emit(Updated { .. })`. Pinned here so that:
7+
/// - `nargo expand` is snapshotted in `noir-projects/contract-snapshots`, making any
8+
/// change to the macro boilerplate visible across all 15 call sites in a single review.
9+
/// - `bytecodeSizeBytes/PublicFnsWithEmitRepro` lands on the bench dashboard, so any
10+
/// improvement (or regression) in the per-public-fn emit shape is tracked over time.
11+
#[aztec]
12+
pub contract PublicFnsWithEmitRepro {
13+
use aztec::macros::events::event;
14+
use aztec::macros::functions::external;
15+
use aztec::macros::storage::storage;
16+
use aztec::state_vars::PublicMutable;
17+
18+
#[event]
19+
struct Updated {
20+
new_value: u64,
21+
}
22+
23+
#[storage]
24+
struct Storage<Context> {
25+
value: PublicMutable<u64, Context>,
26+
}
27+
28+
#[external("public")]
29+
fn fn_01(v: u64) {
30+
let old = self.storage.value.read();
31+
self.storage.value.write(old + v + 1);
32+
self.emit(Updated { new_value: old + v + 1 });
33+
}
34+
#[external("public")]
35+
fn fn_02(v: u64) {
36+
let old = self.storage.value.read();
37+
self.storage.value.write(old + v + 2);
38+
self.emit(Updated { new_value: old + v + 2 });
39+
}
40+
#[external("public")]
41+
fn fn_03(v: u64) {
42+
let old = self.storage.value.read();
43+
self.storage.value.write(old + v + 3);
44+
self.emit(Updated { new_value: old + v + 3 });
45+
}
46+
#[external("public")]
47+
fn fn_04(v: u64) {
48+
let old = self.storage.value.read();
49+
self.storage.value.write(old + v + 4);
50+
self.emit(Updated { new_value: old + v + 4 });
51+
}
52+
#[external("public")]
53+
fn fn_05(v: u64) {
54+
let old = self.storage.value.read();
55+
self.storage.value.write(old + v + 5);
56+
self.emit(Updated { new_value: old + v + 5 });
57+
}
58+
#[external("public")]
59+
fn fn_06(v: u64) {
60+
let old = self.storage.value.read();
61+
self.storage.value.write(old + v + 6);
62+
self.emit(Updated { new_value: old + v + 6 });
63+
}
64+
#[external("public")]
65+
fn fn_07(v: u64) {
66+
let old = self.storage.value.read();
67+
self.storage.value.write(old + v + 7);
68+
self.emit(Updated { new_value: old + v + 7 });
69+
}
70+
#[external("public")]
71+
fn fn_08(v: u64) {
72+
let old = self.storage.value.read();
73+
self.storage.value.write(old + v + 8);
74+
self.emit(Updated { new_value: old + v + 8 });
75+
}
76+
#[external("public")]
77+
fn fn_09(v: u64) {
78+
let old = self.storage.value.read();
79+
self.storage.value.write(old + v + 9);
80+
self.emit(Updated { new_value: old + v + 9 });
81+
}
82+
#[external("public")]
83+
fn fn_10(v: u64) {
84+
let old = self.storage.value.read();
85+
self.storage.value.write(old + v + 10);
86+
self.emit(Updated { new_value: old + v + 10 });
87+
}
88+
#[external("public")]
89+
fn fn_11(v: u64) {
90+
let old = self.storage.value.read();
91+
self.storage.value.write(old + v + 11);
92+
self.emit(Updated { new_value: old + v + 11 });
93+
}
94+
#[external("public")]
95+
fn fn_12(v: u64) {
96+
let old = self.storage.value.read();
97+
self.storage.value.write(old + v + 12);
98+
self.emit(Updated { new_value: old + v + 12 });
99+
}
100+
#[external("public")]
101+
fn fn_13(v: u64) {
102+
let old = self.storage.value.read();
103+
self.storage.value.write(old + v + 13);
104+
self.emit(Updated { new_value: old + v + 13 });
105+
}
106+
#[external("public")]
107+
fn fn_14(v: u64) {
108+
let old = self.storage.value.read();
109+
self.storage.value.write(old + v + 14);
110+
self.emit(Updated { new_value: old + v + 14 });
111+
}
112+
#[external("public")]
113+
fn fn_15(v: u64) {
114+
let old = self.storage.value.read();
115+
self.storage.value.write(old + v + 15);
116+
self.emit(Updated { new_value: old + v + 15 });
117+
}
118+
}

yarn-project/simulator/src/public/public_tx_simulator/apps_tests/bench.test.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { AMMContractArtifact } from '@aztec/noir-contracts.js/AMM';
55
import { TokenContractArtifact } from '@aztec/noir-contracts.js/Token';
66
import { AvmGadgetsTestContractArtifact } from '@aztec/noir-test-contracts.js/AvmGadgetsTest';
77
import { AvmTestContractArtifact } from '@aztec/noir-test-contracts.js/AvmTest';
8+
import { PublicFnsWithEmitReproContractArtifact } from '@aztec/noir-test-contracts.js/PublicFnsWithEmitRepro';
89
import { StorageProofTestContractArtifact } from '@aztec/noir-test-contracts.js/StorageProofTest';
910
import { PublicSimulatorConfig } from '@aztec/stdlib/avm';
1011
import { AztecAddress } from '@aztec/stdlib/aztec-address';
@@ -136,6 +137,32 @@ describe('Public TX simulator apps tests: benchmarks', () => {
136137
expect(result.revertCode.isOK()).toBe(true);
137138
});
138139

140+
it('PublicFnsWithEmitRepro contract test', async () => {
141+
// See comments on the contract source for motivation as to including this contract in our benchmarks.
142+
tester.setMetricsPrefix(`${metricsPrefixPrefix}PublicFnsWithEmitRepro contract tests`);
143+
const deployer = AztecAddress.fromNumber(42);
144+
145+
const reproContract = await tester.registerAndDeployContract(
146+
/*constructorArgs=*/ [],
147+
deployer,
148+
/*contractArtifact=*/ PublicFnsWithEmitReproContractArtifact,
149+
);
150+
151+
const result = await tester.executeTxWithLabel(
152+
/*txLabel=*/ 'PublicFnsWithEmitRepro/fn_01',
153+
/*sender=*/ deployer,
154+
/*setupCalls=*/ [],
155+
/*appCalls=*/ [
156+
{
157+
address: reproContract.address,
158+
fnName: 'fn_01',
159+
args: [/*v=*/ 1n],
160+
},
161+
],
162+
);
163+
expect(result.revertCode.isOK()).toBe(true);
164+
});
165+
139166
it('Storage proof test', async () => {
140167
tester.setMetricsPrefix(`${metricsPrefixPrefix}StorageProof contract tests`);
141168
const deployer = AztecAddress.fromNumber(42);

0 commit comments

Comments
 (0)