@ton/sandbox 0.30.0 → 0.32.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 +17 -1
- package/README.md +104 -0
- package/dist/blockchain/Blockchain.d.ts +16 -2
- package/dist/blockchain/Blockchain.js +31 -13
- package/dist/blockchain/SmartContract.js +2 -0
- package/dist/executor/Executor.d.ts +14 -0
- package/dist/executor/Executor.js +34 -1
- package/dist/executor/emulator-emscripten.js +1 -1
- package/dist/executor/emulator-emscripten.wasm.js +1 -1
- package/dist/index.d.ts +2 -1
- 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/meta/ContractsMeta.d.ts +10 -0
- package/dist/meta/ContractsMeta.js +2 -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 +24 -5
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,22 @@ 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.32.0] - 2025-06-02
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Added contract meta gathering via meta field in blockchain
|
|
13
|
+
- Added ability to set `PREVBLOCKS` information
|
|
14
|
+
|
|
15
|
+
## [0.31.0] - 2025-05-20
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- Added methods to collect metrics of contracts
|
|
20
|
+
- Added `@ton/sandbox/jest-environment` and `@ton/sandbox/jest-reporter` to write metric snapshots from test run results
|
|
21
|
+
- Added contract method ABI auto-mapping mechanism for detailed benchmark metrics
|
|
22
|
+
- Added methods to generate delta reports from metrics of contracts
|
|
23
|
+
|
|
8
24
|
## [0.30.0] - 2025-05-12
|
|
9
25
|
|
|
10
26
|
### Changed
|
|
@@ -383,4 +399,4 @@ type LogsVerbosity = {
|
|
|
383
399
|
|
|
384
400
|
### Removed
|
|
385
401
|
|
|
386
|
-
- Changed `blockchain.pushMessage`, `blockchain.processQueue`, `blockchain.runQueue` to be private
|
|
402
|
+
- 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
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { Address, Cell, Message, Transaction, ContractProvider, Contract, Sender, ShardAccount, TupleItem, ExternalAddress, StateInit, OpenedContract } from "@ton/core";
|
|
2
|
-
import { IExecutor, TickOrTock } from "../executor/Executor";
|
|
2
|
+
import { IExecutor, TickOrTock, PrevBlocksInfo } from "../executor/Executor";
|
|
3
3
|
import { BlockchainStorage } from "./BlockchainStorage";
|
|
4
4
|
import { Event } from "../event/Event";
|
|
5
5
|
import { SandboxContractProvider } from "./BlockchainContractProvider";
|
|
6
6
|
import { TreasuryContract } from "../treasury/Treasury";
|
|
7
7
|
import { GetMethodParams, LogsVerbosity, MessageParams, SmartContract, SmartContractSnapshot, Verbosity } from "./SmartContract";
|
|
8
8
|
import { AsyncLock } from "../utils/AsyncLock";
|
|
9
|
+
import { ContractsMeta } from "../meta/ContractsMeta";
|
|
9
10
|
export type ExternalOutInfo = {
|
|
10
11
|
type: 'external-out';
|
|
11
12
|
src: Address;
|
|
@@ -101,6 +102,8 @@ export declare class Blockchain {
|
|
|
101
102
|
protected contractFetches: Map<string, Promise<SmartContract>>;
|
|
102
103
|
protected nextCreateWalletIndex: number;
|
|
103
104
|
protected shouldRecordStorage: boolean;
|
|
105
|
+
protected meta?: ContractsMeta;
|
|
106
|
+
protected prevBlocksInfo?: PrevBlocksInfo;
|
|
104
107
|
readonly executor: IExecutor;
|
|
105
108
|
/**
|
|
106
109
|
* Saves snapshot of current blockchain.
|
|
@@ -143,6 +146,7 @@ export declare class Blockchain {
|
|
|
143
146
|
executor: IExecutor;
|
|
144
147
|
config?: BlockchainConfig;
|
|
145
148
|
storage: BlockchainStorage;
|
|
149
|
+
meta?: ContractsMeta;
|
|
146
150
|
});
|
|
147
151
|
/**
|
|
148
152
|
* @returns Config used in blockchain.
|
|
@@ -152,6 +156,15 @@ export declare class Blockchain {
|
|
|
152
156
|
* @returns Config used in blockchain in base64 format.
|
|
153
157
|
*/
|
|
154
158
|
get configBase64(): string;
|
|
159
|
+
/**
|
|
160
|
+
* @returns Current PrevBlocksInfo
|
|
161
|
+
*/
|
|
162
|
+
get prevBlocks(): PrevBlocksInfo | undefined;
|
|
163
|
+
/**
|
|
164
|
+
* Sets PrevBlocksInfo.
|
|
165
|
+
* @param value PrevBlocksInfo to set
|
|
166
|
+
*/
|
|
167
|
+
set prevBlocks(value: PrevBlocksInfo | undefined);
|
|
155
168
|
/**
|
|
156
169
|
* Emulates the result of sending a message to this Blockchain. Emulates the whole chain of transactions before returning the result. Each transaction increases lt by 1000000.
|
|
157
170
|
*
|
|
@@ -329,7 +342,7 @@ export declare class Blockchain {
|
|
|
329
342
|
* @param [opts.executor] Custom contract executor. If omitted {@link Executor} is used.
|
|
330
343
|
* @param [opts.config] Config used in blockchain. If omitted {@link defaultConfig} is used.
|
|
331
344
|
* @param [opts.storage] Contracts storage used for blockchain. If omitted {@link LocalBlockchainStorage} is used.
|
|
332
|
-
*
|
|
345
|
+
* @param [opts.meta] Optional contracts metadata provider. If not provided, {@link @ton/test-utils.contractsMeta} will be used to accumulate contracts metadata.
|
|
333
346
|
* @example
|
|
334
347
|
* const blockchain = await Blockchain.create({ config: 'slim' });
|
|
335
348
|
*
|
|
@@ -346,6 +359,7 @@ export declare class Blockchain {
|
|
|
346
359
|
executor?: IExecutor;
|
|
347
360
|
config?: BlockchainConfig;
|
|
348
361
|
storage?: BlockchainStorage;
|
|
362
|
+
meta?: ContractsMeta;
|
|
349
363
|
}): Promise<Blockchain>;
|
|
350
364
|
}
|
|
351
365
|
export {};
|
|
@@ -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}`;
|
|
@@ -129,6 +130,7 @@ class Blockchain {
|
|
|
129
130
|
this.networkConfig = blockchainConfigToBase64(opts.config);
|
|
130
131
|
this.executor = opts.executor;
|
|
131
132
|
this.storage = opts.storage;
|
|
133
|
+
this.meta = opts.meta;
|
|
132
134
|
}
|
|
133
135
|
/**
|
|
134
136
|
* @returns Config used in blockchain.
|
|
@@ -142,6 +144,19 @@ class Blockchain {
|
|
|
142
144
|
get configBase64() {
|
|
143
145
|
return this.networkConfig;
|
|
144
146
|
}
|
|
147
|
+
/**
|
|
148
|
+
* @returns Current PrevBlocksInfo
|
|
149
|
+
*/
|
|
150
|
+
get prevBlocks() {
|
|
151
|
+
return this.prevBlocksInfo;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Sets PrevBlocksInfo.
|
|
155
|
+
* @param value PrevBlocksInfo to set
|
|
156
|
+
*/
|
|
157
|
+
set prevBlocks(value) {
|
|
158
|
+
this.prevBlocksInfo = value;
|
|
159
|
+
}
|
|
145
160
|
/**
|
|
146
161
|
* Emulates the result of sending a message to this Blockchain. Emulates the whole chain of transactions before returning the result. Each transaction increases lt by 1000000.
|
|
147
162
|
*
|
|
@@ -400,6 +415,7 @@ class Blockchain {
|
|
|
400
415
|
else if ((params?.resetBalanceIfZero ?? true) && contract.balance === 0n) {
|
|
401
416
|
contract.balance = params?.balance ?? (0, core_1.toNano)(TREASURY_INIT_BALANCE_TONS);
|
|
402
417
|
}
|
|
418
|
+
this.meta?.upsert(wallet.address, { treasurySeed: seed });
|
|
403
419
|
return wallet;
|
|
404
420
|
}
|
|
405
421
|
/**
|
|
@@ -443,6 +459,7 @@ class Blockchain {
|
|
|
443
459
|
}
|
|
444
460
|
init = contract.init;
|
|
445
461
|
}
|
|
462
|
+
this.meta?.upsert(address, { wrapperName: contract?.constructor?.name, abi: contract.abi });
|
|
446
463
|
const provider = this.provider(address, init);
|
|
447
464
|
const blkch = this;
|
|
448
465
|
return new Proxy(contract, {
|
|
@@ -452,25 +469,25 @@ class Blockchain {
|
|
|
452
469
|
}
|
|
453
470
|
const value = target[prop];
|
|
454
471
|
if (typeof prop === 'string' && typeof value === 'function') {
|
|
472
|
+
const ctx = {
|
|
473
|
+
contract,
|
|
474
|
+
methodName: prop,
|
|
475
|
+
};
|
|
455
476
|
if (prop.startsWith('get')) {
|
|
456
477
|
return (...args) => value.apply(target, [provider, ...args]);
|
|
457
478
|
}
|
|
458
479
|
else if (prop.startsWith('send')) {
|
|
459
480
|
return async (...args) => {
|
|
460
|
-
|
|
481
|
+
let ret = value.apply(target, [provider, ...args]);
|
|
461
482
|
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
|
-
};
|
|
483
|
+
ret = await ret;
|
|
473
484
|
}
|
|
485
|
+
const out = {
|
|
486
|
+
...await blkch.runQueue(),
|
|
487
|
+
result: ret,
|
|
488
|
+
};
|
|
489
|
+
await (0, collectMetric_1.collectMetric)(blkch, ctx, out);
|
|
490
|
+
return out;
|
|
474
491
|
};
|
|
475
492
|
}
|
|
476
493
|
}
|
|
@@ -564,7 +581,7 @@ class Blockchain {
|
|
|
564
581
|
* @param [opts.executor] Custom contract executor. If omitted {@link Executor} is used.
|
|
565
582
|
* @param [opts.config] Config used in blockchain. If omitted {@link defaultConfig} is used.
|
|
566
583
|
* @param [opts.storage] Contracts storage used for blockchain. If omitted {@link LocalBlockchainStorage} is used.
|
|
567
|
-
*
|
|
584
|
+
* @param [opts.meta] Optional contracts metadata provider. If not provided, {@link @ton/test-utils.contractsMeta} will be used to accumulate contracts metadata.
|
|
568
585
|
* @example
|
|
569
586
|
* const blockchain = await Blockchain.create({ config: 'slim' });
|
|
570
587
|
*
|
|
@@ -581,6 +598,7 @@ class Blockchain {
|
|
|
581
598
|
return new Blockchain({
|
|
582
599
|
executor: opts?.executor ?? await Executor_1.Executor.create(),
|
|
583
600
|
storage: opts?.storage ?? new BlockchainStorage_1.LocalBlockchainStorage(),
|
|
601
|
+
meta: opts?.meta ?? require('@ton/test-utils')?.contractsMeta,
|
|
584
602
|
...opts
|
|
585
603
|
});
|
|
586
604
|
}
|
|
@@ -214,6 +214,7 @@ class SmartContract {
|
|
|
214
214
|
randomSeed: params?.randomSeed ?? Buffer.alloc(32),
|
|
215
215
|
ignoreChksig: params?.ignoreChksig ?? false,
|
|
216
216
|
debugEnabled: this.verbosity.debugLogs,
|
|
217
|
+
prevBlocksInfo: this.blockchain.prevBlocks,
|
|
217
218
|
};
|
|
218
219
|
}
|
|
219
220
|
async receiveMessage(message, params) {
|
|
@@ -287,6 +288,7 @@ class SmartContract {
|
|
|
287
288
|
gasLimit: params?.gasLimit ?? 10000000n,
|
|
288
289
|
debugEnabled: this.verbosity.debugLogs,
|
|
289
290
|
extraCurrency: this.ec,
|
|
291
|
+
prevBlocksInfo: this.blockchain.prevBlocks,
|
|
290
292
|
});
|
|
291
293
|
if (this.verbosity.print && this.verbosity.blockchainLogs && res.logs.length > 0) {
|
|
292
294
|
console.log(res.logs);
|
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { Address, Cell, TupleItem } from "@ton/core";
|
|
3
3
|
import { ExtraCurrency } from "../utils/ec";
|
|
4
|
+
export type BlockId = {
|
|
5
|
+
workchain: number;
|
|
6
|
+
shard: bigint;
|
|
7
|
+
seqno: number;
|
|
8
|
+
rootHash: Buffer;
|
|
9
|
+
fileHash: Buffer;
|
|
10
|
+
};
|
|
11
|
+
export type PrevBlocksInfo = {
|
|
12
|
+
lastMcBlocks: BlockId[];
|
|
13
|
+
prevKeyBlock: BlockId;
|
|
14
|
+
lastMcBlocks100?: BlockId[];
|
|
15
|
+
};
|
|
4
16
|
export type GetMethodArgs = {
|
|
5
17
|
code: Cell;
|
|
6
18
|
data: Cell;
|
|
@@ -16,6 +28,7 @@ export type GetMethodArgs = {
|
|
|
16
28
|
gasLimit: bigint;
|
|
17
29
|
debugEnabled: boolean;
|
|
18
30
|
extraCurrency?: ExtraCurrency;
|
|
31
|
+
prevBlocksInfo?: PrevBlocksInfo;
|
|
19
32
|
};
|
|
20
33
|
export type GetMethodResultSuccess = {
|
|
21
34
|
success: true;
|
|
@@ -44,6 +57,7 @@ export type RunCommonArgs = {
|
|
|
44
57
|
randomSeed: Buffer | null;
|
|
45
58
|
ignoreChksig: boolean;
|
|
46
59
|
debugEnabled: boolean;
|
|
60
|
+
prevBlocksInfo?: PrevBlocksInfo;
|
|
47
61
|
};
|
|
48
62
|
export type RunTransactionArgs = {
|
|
49
63
|
message: Cell;
|
|
@@ -4,6 +4,32 @@ exports.Executor = void 0;
|
|
|
4
4
|
const core_1 = require("@ton/core");
|
|
5
5
|
const base64_1 = require("../utils/base64");
|
|
6
6
|
const EmulatorModule = require('./emulator-emscripten.js');
|
|
7
|
+
function blockIdToTuple(blockId) {
|
|
8
|
+
return [
|
|
9
|
+
{ type: 'int', value: BigInt(blockId.workchain) },
|
|
10
|
+
{ type: 'int', value: blockId.shard },
|
|
11
|
+
{ type: 'int', value: BigInt(blockId.seqno) },
|
|
12
|
+
{ type: 'int', value: BigInt('0x' + blockId.rootHash.toString('hex')) },
|
|
13
|
+
{ type: 'int', value: BigInt('0x' + blockId.fileHash.toString('hex')) },
|
|
14
|
+
];
|
|
15
|
+
}
|
|
16
|
+
function prevBlocksInfoToTuple(prevBlocksInfo) {
|
|
17
|
+
const r = [
|
|
18
|
+
{ type: 'tuple', items: prevBlocksInfo.lastMcBlocks.map(bid => ({ type: 'tuple', items: blockIdToTuple(bid) })) },
|
|
19
|
+
{ type: 'tuple', items: blockIdToTuple(prevBlocksInfo.prevKeyBlock) },
|
|
20
|
+
];
|
|
21
|
+
if (prevBlocksInfo.lastMcBlocks100) {
|
|
22
|
+
r.push({ type: 'tuple', items: prevBlocksInfo.lastMcBlocks100.map(bid => ({ type: 'tuple', items: blockIdToTuple(bid) })) });
|
|
23
|
+
}
|
|
24
|
+
return r;
|
|
25
|
+
}
|
|
26
|
+
function serializeTupleAsStackEntry(tuple) {
|
|
27
|
+
const c = (0, core_1.serializeTuple)([{ type: 'tuple', items: tuple }]);
|
|
28
|
+
const s = c.beginParse();
|
|
29
|
+
s.skip(24);
|
|
30
|
+
s.loadRef();
|
|
31
|
+
return s.asCell();
|
|
32
|
+
}
|
|
7
33
|
const verbosityToNum = {
|
|
8
34
|
'short': 0,
|
|
9
35
|
'full': 1,
|
|
@@ -13,13 +39,17 @@ const verbosityToNum = {
|
|
|
13
39
|
'full_location_stack_verbose': 5,
|
|
14
40
|
};
|
|
15
41
|
function runCommonArgsToInternalParams(args) {
|
|
16
|
-
|
|
42
|
+
const p = {
|
|
17
43
|
utime: args.now,
|
|
18
44
|
lt: args.lt.toString(),
|
|
19
45
|
rand_seed: args.randomSeed === null ? '' : args.randomSeed.toString('hex'),
|
|
20
46
|
ignore_chksig: args.ignoreChksig,
|
|
21
47
|
debug_enabled: args.debugEnabled,
|
|
22
48
|
};
|
|
49
|
+
if (args.prevBlocksInfo !== undefined) {
|
|
50
|
+
p.prev_blocks_info = serializeTupleAsStackEntry(prevBlocksInfoToTuple(args.prevBlocksInfo)).toBoc().toString('base64');
|
|
51
|
+
}
|
|
52
|
+
return p;
|
|
23
53
|
}
|
|
24
54
|
class Pointer {
|
|
25
55
|
constructor(length, rawPointer) {
|
|
@@ -99,6 +129,9 @@ class Executor {
|
|
|
99
129
|
params.extra_currencies[k] = v.toString();
|
|
100
130
|
}
|
|
101
131
|
}
|
|
132
|
+
if (args.prevBlocksInfo !== undefined) {
|
|
133
|
+
params.prev_blocks_info = serializeTupleAsStackEntry(prevBlocksInfoToTuple(args.prevBlocksInfo)).toBoc().toString('base64');
|
|
134
|
+
}
|
|
102
135
|
let stack = (0, core_1.serializeTuple)(args.stack);
|
|
103
136
|
this.debugLogs = [];
|
|
104
137
|
const resp = JSON.parse(this.extractString(this.invoke('_run_get_method', [
|