@ton/sandbox 0.29.0 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -1
- package/README.md +104 -0
- package/dist/blockchain/Blockchain.js +13 -12
- package/dist/config/defaultConfig.d.ts +2 -2
- package/dist/config/defaultConfig.js +2 -2
- package/dist/config/slimConfig.d.ts +2 -2
- package/dist/config/slimConfig.js +2 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +15 -0
- package/dist/jest/BenchmarkCommand.d.ts +10 -0
- package/dist/jest/BenchmarkCommand.js +14 -0
- package/dist/jest/BenchmarkEnvironment.d.ts +19 -0
- package/dist/jest/BenchmarkEnvironment.js +46 -0
- package/dist/jest/BenchmarkReporter.d.ts +45 -0
- package/dist/jest/BenchmarkReporter.js +207 -0
- package/dist/metric/ContractDatabase.d.ts +21 -0
- package/dist/metric/ContractDatabase.js +111 -0
- package/dist/metric/collectMetric.d.ts +106 -0
- package/dist/metric/collectMetric.js +217 -0
- package/dist/metric/defaultColor.d.ts +2 -0
- package/dist/metric/defaultColor.js +45 -0
- package/dist/metric/deltaResult.d.ts +39 -0
- package/dist/metric/deltaResult.js +210 -0
- package/dist/metric/gasReportTable.d.ts +2 -0
- package/dist/metric/gasReportTable.js +112 -0
- package/dist/metric/index.d.ts +6 -0
- package/dist/metric/index.js +22 -0
- package/dist/metric/readSnapshots.d.ts +2 -0
- package/dist/metric/readSnapshots.js +33 -0
- package/dist/utils/readJsonl.d.ts +1 -0
- package/dist/utils/readJsonl.js +25 -0
- package/jest-environment.js +1 -0
- package/jest-reporter.js +1 -0
- package/package.json +18 -4
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,21 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.31.0] - 2025-05-20
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Added methods to collect metrics of contracts
|
|
13
|
+
- Added `@ton/sandbox/jest-environment` and `@ton/sandbox/jest-reporter` to write metric snapshots from test run results
|
|
14
|
+
- Added contract method ABI auto-mapping mechanism for detailed benchmark metrics
|
|
15
|
+
- Added methods to generate delta reports from metrics of contracts
|
|
16
|
+
|
|
17
|
+
## [0.30.0] - 2025-05-12
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- Updated config
|
|
22
|
+
|
|
8
23
|
## [0.29.0] - 2025-04-30
|
|
9
24
|
|
|
10
25
|
### Changed
|
|
@@ -377,4 +392,4 @@ type LogsVerbosity = {
|
|
|
377
392
|
|
|
378
393
|
### Removed
|
|
379
394
|
|
|
380
|
-
- Changed `blockchain.pushMessage`, `blockchain.processQueue`, `blockchain.runQueue` to be private
|
|
395
|
+
- Changed `blockchain.pushMessage`, `blockchain.processQueue`, `blockchain.runQueue` to be private
|
package/README.md
CHANGED
|
@@ -15,6 +15,7 @@ The key difference of this package from [ton-contract-executor](https://github.c
|
|
|
15
15
|
* [Cross contract tests](#cross-contract-tests)
|
|
16
16
|
* [Testing key points](#testing-key-points)
|
|
17
17
|
* [Test examples](#test-examples)
|
|
18
|
+
* [Benchmark contracts](#benchmark-contracts)
|
|
18
19
|
* [Sandbox pitfalls](#sandbox-pitfalls)
|
|
19
20
|
* [Viewing logs](#viewing-logs)
|
|
20
21
|
* [Setting smart contract state directly](#setting-smart-contract-state-directly)
|
|
@@ -290,6 +291,109 @@ Learn more from examples:
|
|
|
290
291
|
* [FunC Test Examples](https://docs.ton.org/develop/smart-contracts/examples#examples-of-tests-for-smart-contracts)
|
|
291
292
|
* [Tact Test Examples](docs/tact-testing-examples.md)
|
|
292
293
|
|
|
294
|
+
## Benchmark contracts
|
|
295
|
+
|
|
296
|
+
The `@ton/sandbox` package provides `@ton/sandbox/jest-environment` and `@ton/sandbox/jest-reporter` built-in support for benchmarking smart contract behavior during tests, including tracking gas usage, cell size, opcode execution, and action phases.
|
|
297
|
+
This is especially useful for performance analysis, gas optimization, and regression checks on contract logic.
|
|
298
|
+
|
|
299
|
+
> ℹ️ See also: [Collect metric API](docs/collect-metric-api.md) for low-level control and manual snapshots.
|
|
300
|
+
|
|
301
|
+
### Features
|
|
302
|
+
|
|
303
|
+
* Automatic metric collection from all transactions triggered during tests
|
|
304
|
+
* Snapshot reporting with contract-level filters
|
|
305
|
+
* Integration with [blueprint](https://github.com/ton-org/blueprint#benchmark-contracts)
|
|
306
|
+
|
|
307
|
+
### Setup in `jest.config.ts`
|
|
308
|
+
|
|
309
|
+
```ts
|
|
310
|
+
import type { Config } from 'jest';
|
|
311
|
+
|
|
312
|
+
const config: Config = {
|
|
313
|
+
preset: 'ts-jest',
|
|
314
|
+
testEnvironment: '@ton/sandbox/jest-environment',
|
|
315
|
+
globalSetup: './jest.setup.ts',
|
|
316
|
+
testPathIgnorePatterns: ['/node_modules/', '/dist/'],
|
|
317
|
+
reporters: [
|
|
318
|
+
'default',
|
|
319
|
+
['@ton/sandbox/jest-reporter', {
|
|
320
|
+
// options
|
|
321
|
+
snapshotDir: '.snapshot', // output folder for benchmark reports, default: '.snapshot'
|
|
322
|
+
contractDatabase: 'contract.abi.json', // path or json a map of known contracts, see Collect metric API, default: 'contract.abi.json'
|
|
323
|
+
reportName: 'gas-report', // report name, default: 'gas-report'
|
|
324
|
+
depthCompare: 2, // comparison depth, default: 2
|
|
325
|
+
removeRawResult: true, // remove raw metric file, default: true
|
|
326
|
+
contractExcludes: [ // exclude specific contracts from snapshot, default: []
|
|
327
|
+
'TreasuryContract',
|
|
328
|
+
],
|
|
329
|
+
}],
|
|
330
|
+
],
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
export default config;
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### How to run benchmarks
|
|
337
|
+
|
|
338
|
+
To collect and save snapshot metrics:
|
|
339
|
+
|
|
340
|
+
```bash
|
|
341
|
+
BENCH_NEW="some" npx jest
|
|
342
|
+
# or
|
|
343
|
+
npx blueprint snapshot --label "some"
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
This will:
|
|
347
|
+
|
|
348
|
+
* Run your tests
|
|
349
|
+
* Collect contract execution metrics
|
|
350
|
+
* Save a snapshot in `.snapshot/<timestamp>.json`
|
|
351
|
+
|
|
352
|
+
To compare with a previous snapshot:
|
|
353
|
+
|
|
354
|
+
```bash
|
|
355
|
+
BENCH_DIFF=true npx jest
|
|
356
|
+
# or
|
|
357
|
+
npx blueprint test --gas-report
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
### Or setup in `gas-report.config.ts`
|
|
361
|
+
|
|
362
|
+
```ts
|
|
363
|
+
import config from './jest.config';
|
|
364
|
+
|
|
365
|
+
config.testNamePattern = '^DescribeName .* - test name$'
|
|
366
|
+
config.testEnvironment = '@ton/sandbox/jest-environment'
|
|
367
|
+
config.reporters = [
|
|
368
|
+
['@ton/sandbox/jest-reporter', {
|
|
369
|
+
contractDatabase: 'abi.json',
|
|
370
|
+
contractExcludes: [
|
|
371
|
+
'TreasuryContract',
|
|
372
|
+
],
|
|
373
|
+
}],
|
|
374
|
+
]
|
|
375
|
+
export default config;
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
**Collect metric and get report:**
|
|
379
|
+
|
|
380
|
+
```bash
|
|
381
|
+
npx blueprint snapshot --label "some label" -- --config gas-report.config.ts
|
|
382
|
+
npx blueprint test --gas-report -- --config gas-report.config.ts
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
### Output structure
|
|
386
|
+
|
|
387
|
+
By default, the reporter generates:
|
|
388
|
+
|
|
389
|
+
```
|
|
390
|
+
.project-root/
|
|
391
|
+
├── .snapshot/
|
|
392
|
+
│ └── 4200000000000.json // timestamped snapshot file
|
|
393
|
+
├── .sandbox-metric-raw.jsonl // raw metric log (auto-deleted by default)
|
|
394
|
+
├── contract.abi.json // map of known contracts, see Collect metric API
|
|
395
|
+
└── gas-report.json // aggregate report in json format
|
|
396
|
+
```
|
|
293
397
|
|
|
294
398
|
## Sandbox pitfalls
|
|
295
399
|
|
|
@@ -13,6 +13,7 @@ const AsyncLock_1 = require("../utils/AsyncLock");
|
|
|
13
13
|
const message_1 = require("../utils/message");
|
|
14
14
|
const slimConfig_1 = require("../config/slimConfig");
|
|
15
15
|
const testTreasurySubwalletId_1 = require("../utils/testTreasurySubwalletId");
|
|
16
|
+
const collectMetric_1 = require("../metric/collectMetric");
|
|
16
17
|
const CREATE_WALLETS_PREFIX = 'CREATE_WALLETS';
|
|
17
18
|
function createWalletsSeed(idx) {
|
|
18
19
|
return `${CREATE_WALLETS_PREFIX}${idx}`;
|
|
@@ -452,25 +453,25 @@ class Blockchain {
|
|
|
452
453
|
}
|
|
453
454
|
const value = target[prop];
|
|
454
455
|
if (typeof prop === 'string' && typeof value === 'function') {
|
|
456
|
+
const ctx = {
|
|
457
|
+
contract,
|
|
458
|
+
methodName: prop,
|
|
459
|
+
};
|
|
455
460
|
if (prop.startsWith('get')) {
|
|
456
461
|
return (...args) => value.apply(target, [provider, ...args]);
|
|
457
462
|
}
|
|
458
463
|
else if (prop.startsWith('send')) {
|
|
459
464
|
return async (...args) => {
|
|
460
|
-
|
|
465
|
+
let ret = value.apply(target, [provider, ...args]);
|
|
461
466
|
if (ret instanceof Promise) {
|
|
462
|
-
|
|
463
|
-
return {
|
|
464
|
-
...await blkch.runQueue(),
|
|
465
|
-
result: r,
|
|
466
|
-
};
|
|
467
|
-
}
|
|
468
|
-
else {
|
|
469
|
-
return {
|
|
470
|
-
...await blkch.runQueue(),
|
|
471
|
-
result: ret,
|
|
472
|
-
};
|
|
467
|
+
ret = await ret;
|
|
473
468
|
}
|
|
469
|
+
const out = {
|
|
470
|
+
...await blkch.runQueue(),
|
|
471
|
+
result: ret,
|
|
472
|
+
};
|
|
473
|
+
await (0, collectMetric_1.collectMetric)(blkch, ctx, out);
|
|
474
|
+
return out;
|
|
474
475
|
};
|
|
475
476
|
}
|
|
476
477
|
}
|