@@ -135,15 +135,9 @@ function gas_report {
135
135
function gas_benchmark {
136
136
check=${1:- " no" }
137
137
echo_header " Benchmarking gas"
138
- forge --version
139
138
140
- FORGE_GAS_REPORT=true forge test \
141
- --match-contract " BenchmarkRollupTest" \
142
- --fuzz-seed 42 \
143
- --isolate \
144
- > gas_benchmark.new.tmp
145
- grep " ^|" gas_benchmark.new.tmp > gas_benchmark.new.md
146
- rm gas_benchmark.new.tmp
139
+ validator_costs
140
+
147
141
diff gas_benchmark.new.md gas_benchmark.md > gas_benchmark.diff || true
148
142
149
143
if [ -s gas_benchmark.diff -a " $check " = " check" ]; then
@@ -154,6 +148,125 @@ function gas_benchmark {
154
148
mv gas_benchmark.new.md gas_benchmark.md
155
149
}
156
150
151
+ function validator_costs {
152
+ echo_header " Comparing gas costs with and without validators"
153
+ forge --version
154
+
155
+ # Run test without validators
156
+ echo " Running test without validators..."
157
+ FORGE_GAS_REPORT=true forge test \
158
+ --match-contract " BenchmarkRollupTest" \
159
+ --match-test " test_no_validators" \
160
+ --fuzz-seed 42 \
161
+ --isolate \
162
+ > no_validators.tmp
163
+
164
+ # Run test with 100 validators
165
+ echo " Running test with 100 validators..."
166
+ FORGE_GAS_REPORT=true forge test \
167
+ --match-contract " BenchmarkRollupTest" \
168
+ --match-test " test_100_validators" \
169
+ --fuzz-seed 42 \
170
+ --isolate \
171
+ > with_validators.tmp
172
+
173
+ file_no=" no_validators.tmp" # without validators
174
+ file_yes=" with_validators.tmp" # with validators
175
+ report=" gas_benchmark.new.md" # will be overwritten each run
176
+
177
+ # keep ONLY these functions, in this order
178
+ wanted_funcs=" forward submitEpochRootProof"
179
+
180
+ # one label per numeric column (use | to separate)
181
+ labels=' Min|Avg|Median|Max|# Calls'
182
+
183
+ awk -v keep=" $wanted_funcs " -v lbl=" $labels " \
184
+ -v f_no=" $file_no " -v f_yes=" $file_yes " '
185
+ function trim(s){gsub(/^[[:space:]]+|[[:space:]]+$/,"",s); return s}
186
+ # cell(raw [, scaled])
187
+ # If you call it with ONE argument, you get the raw value only.
188
+ # If you call it with TWO arguments, you get "raw (scaled)" padded to 22.
189
+ function cell(raw, scaled, s) {
190
+ # Was a second parameter supplied?
191
+ if ( scaled == "" ) # argument omitted → print raw only
192
+ return sprintf("%22d", raw)
193
+
194
+ s = sprintf("%10d (%.2f)", raw, scaled)
195
+ return sprintf("%-22s", s) # left-pad / truncate to 22 chars
196
+ }
197
+
198
+ BEGIN{
199
+ # ---------------- wanted functions & labels (unchanged) ---------------
200
+ nf = split(keep, F, /[[:space:]]+/)
201
+ for (i = 1; i <= nf; i++) { order[i] = F[i]; want[F[i]] }
202
+ split(lbl, L, /\|/); nLab = length(L)
203
+
204
+ # ---------------- fixed-width formats ---------------------------------
205
+ # header row
206
+ hdr = "%-24s | %-7s | %22s | %23s | %22s | %12s\n"
207
+ sep = "-------------------------+---------+------------------------+-------------------------+------------------------+-----------------"
208
+ # data row (the three %22s will already be fully padded strings)
209
+ row = "%-24s | %-7s | %22s | %23s | %22s | %10.2f%%\n"
210
+
211
+ printf hdr, "Function", "Metric",
212
+ "No Validators (gas/tx)", "100 Validators (gas/tx)", "Δ Gas (gas/tx)", "% Overhead"
213
+ print sep
214
+
215
+ FS="|"; OFS=""
216
+ }
217
+ # ---------- first file: without validators ----------------------------------
218
+ FNR==NR {
219
+ if($0 !~ /^\|/) next
220
+ split($0, C) # C[1] "", C[2] fn, C[3..] numbers
221
+ fn = trim(C[2])
222
+ if(!(fn in want)) next
223
+ for(i=3; i<=NF-1; i++) base[fn,i] = trim(C[i]) + 0
224
+ cols[fn] = NF - 3 # remember how many numeric cols
225
+ next
226
+ }
227
+ # ---------- second file: with validators ------------------------------------
228
+ {
229
+ if($0 !~ /^\|/) next
230
+ split($0, C)
231
+ fn = trim(C[2])
232
+ if(!(fn in want)) next
233
+ for(i=3; i<=NF-1; i++) with[fn,i] = trim(C[i]) + 0
234
+ cols[fn] = NF - 3
235
+ }
236
+ # ---------- emit table -------------------------------------------------------
237
+ END{
238
+ for (k = 1; k <= nf; k++) {
239
+ fn = order[k]
240
+ div = (fn == "forward" ? 360 : 11520) # change 11520→720 if desired
241
+
242
+ for (j = 1; j <= cols[fn]; j++) {
243
+ idx = j + 2
244
+ metric = L[j]
245
+ a = base[fn,idx] + 0
246
+ b = with[fn,idx] + 0
247
+ diff = b - a
248
+ pct = (a ? diff * 100.0 / a : 0)
249
+
250
+ if (metric == "# Calls") {
251
+ c1 = cell(a)
252
+ c2 = cell(b)
253
+ c3 = cell(diff)
254
+ } else {
255
+ c1 = cell(a, a/div)
256
+ c2 = cell(b, b/div)
257
+ c3 = cell(diff,diff/div)
258
+ }
259
+ printf row, fn, metric, c1, c2, c3, pct
260
+ }
261
+ print sep
262
+ }
263
+ }
264
+ ' " $file_no " " $file_yes " > " $report "
265
+
266
+ # Clean up temporary files
267
+ rm no_validators.tmp with_validators.tmp
268
+ }
269
+
157
270
# First argument is a branch name (e.g. master, or the latest version e.g. 1.2.3) to push to the head of.
158
271
# Second argument is the tag name (e.g. v1.2.3, or commit-<hash>).
159
272
# Third argument is the semver for package.json (e.g. 1.2.3 or 1.2.3-commit.<hash>)
0 commit comments