diff --git a/CHANGELOG.md b/CHANGELOG.md index e5a6df838..c3871e2be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Optional types for `self` argument in `extends mutates` functions are now allowed: PR [#854](https://github.com/tact-lang/tact/pull/854) - Error codes in the report are now formatted as a list: PR [#1051](https://github.com/tact-lang/tact/pull/1051) - Clarify error message for bounced types from which accessed a field that does not fit in 224 bytes: PR [#1111](https://github.com/tact-lang/tact/pull/1111) +- Do not automatically validate all addresses when receiving/sending messages or using address manipulating functions: PR [#1207](https://github.com/tact-lang/tact/pull/1207) +- Remove `enabledMasterchain` compiler config option from `tact.config.json`: PR [#1207](https://github.com/tact-lang/tact/pull/1207) +- Remove `org.ton.chain.any.v0` interface: PR [#1207](https://github.com/tact-lang/tact/pull/1207) ### Fixed diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs index 61d5bd0c6..65b3500ea 100644 --- a/docs/astro.config.mjs +++ b/docs/astro.config.mjs @@ -186,7 +186,6 @@ export default defineConfig({ { slug: 'book/upgrades' }, { slug: 'book/import' }, { slug: 'book/config' }, - { slug: 'book/masterchain' }, { slug: 'book/func' }, { slug: 'book/security-best-practices' }, ], diff --git a/docs/cspell.json b/docs/cspell.json index ef92d9e55..7b2c12f56 100644 --- a/docs/cspell.json +++ b/docs/cspell.json @@ -156,7 +156,6 @@ "lvalue", "lvalues", "masterchain", - "masterchain", "mathrm", "maxint", "minmax", diff --git a/docs/src/content/docs/book/cells.mdx b/docs/src/content/docs/book/cells.mdx index 621c8e36d..9e5e5cb9a 100644 --- a/docs/src/content/docs/book/cells.mdx +++ b/docs/src/content/docs/book/cells.mdx @@ -21,7 +21,7 @@ Kinds (or subtypes) of all cells are encoded by an integer between $-1$ and $255 [TVM][tvm] currently supports the following exotic cell subtypes: * [Pruned branch cell][c-pruned], with subtype encoded as $1$ — they represent deleted subtrees of cells. -* [Library reference cell][c-library], with subtype encoded as $2$ — they are used for storing libraries, and usually, in [masterchain](/book/masterchain) contexts. +* [Library reference cell][c-library], with subtype encoded as $2$ — they are used for storing libraries, and usually, in [masterchain][masterchain] contexts. * [Merkle proof cell][c-mproof], with subtype encoded as $3$ — they are used for verifying that certain portions of other cell's tree data belong to the full tree. * [Merkle update cell][c-mupdate], with subtype encoded as $4$ — they always have two references and behave like a [Merkle proof][mproof] for both of them. @@ -40,6 +40,7 @@ Kinds (or subtypes) of all cells are encoded by an integer between $-1$ and $255 [c-mproof]: https://docs.ton.org/develop/data-formats/exotic-cells#merkle-proof [c-mupdate]: https://docs.ton.org/develop/data-formats/exotic-cells#merkle-update [mproof]: https://docs.ton.org/develop/data-formats/exotic-cells#simple-proof-verifying-example +[masterchain]: https://docs.ton.org/v3/documentation/smart-contracts/shards/shards-intro#masterchain ### Levels {#cells-levels} diff --git a/docs/src/content/docs/book/config.mdx b/docs/src/content/docs/book/config.mdx index 416856a85..10c5ded51 100644 --- a/docs/src/content/docs/book/config.mdx +++ b/docs/src/content/docs/book/config.mdx @@ -149,39 +149,6 @@ If set to `true{:json}`, enables debug output of a contract and allows usage of ::: -#### `masterchain` {#options-masterchain} - -`false{:json}` by default. - -If set to `true{:json}`, enables [masterchain](/book/masterchain) support. - -```json filename="tact.config.json" {8,14} -{ - "projects": [ - { - "name": "some_prefix", - "path": "./contract.tact", - "output": "./contract_output", - "options": { - "masterchain": true - } - }, - { - "name": "ContractUnderBlueprint", - "options": { - "masterchain": true - } - } - ] -} -``` - -:::note - - Read more on the dedicated page: [Masterchain](/book/masterchain). - -::: - #### `external` {#options-external} `false{:json}` by default. @@ -399,7 +366,6 @@ In [Blueprint][bp], `mode` is always set to `"full"{:json}` and cannot be overwr "name": "ContractUnderBlueprint", "options": { "debug": false, - "masterchain": false, "external": false, "ipfsAbiGetter": true, "interfacesGetter": true, diff --git a/docs/src/content/docs/book/contracts.mdx b/docs/src/content/docs/book/contracts.mdx index dfc317fc4..cacab40c2 100644 --- a/docs/src/content/docs/book/contracts.mdx +++ b/docs/src/content/docs/book/contracts.mdx @@ -95,7 +95,6 @@ Tact has a small set of interfaces provided under specific conditions: * `"org.ton.abi.ipfs.v0"{:tact}`, in accordance to [OTP-003: Self-ABI Reporting](/ref/evolution/otp-003) — opt-in via [`ipfsAbiGetter`](/book/config#options-ipfsabigetter) config property * `"org.ton.deploy.lazy.v0"{:tact}`, in accordance to [OTP-005: Argument-addressable contracts](/ref/evolution/otp-005) * `"org.ton.debug.v0"{:tact}`, but only if [debug mode](/book/debug#debug-mode) is enabled -* `"org.ton.chain.any.v0"{:tact}` if [masterchain](/book/masterchain) support is enabled, and `"org.ton.chain.workchain.v0"{:tact}` otherwise Some [traits][trait] in [standard libraries](/ref/standard-libraries) define their interfaces too: diff --git a/docs/src/content/docs/book/exit-codes.mdx b/docs/src/content/docs/book/exit-codes.mdx index bfb6486b7..cc1ca41f6 100644 --- a/docs/src/content/docs/book/exit-codes.mdx +++ b/docs/src/content/docs/book/exit-codes.mdx @@ -3,6 +3,8 @@ title: Exit codes description: "An exit code is a 32-bit signed integer, which indicates whether the compute or action phase of the transaction was successful, and if not — holds the code of the exception occurred" --- +import { Badge } from '@astrojs/starlight/components'; + Each transaction on TON Blockchain consists of [multiple phases](https://docs.ton.org/learn/tvm-instructions/tvm-overview#transactions-and-phases). An _exit code_ is a $32$-bit signed integer, which indicates whether the [compute](#compute) or [action](#action) phase of the transaction was successful, and if not — holds the code of the exception occurred. Each exit code represents its own exception or resulting state of the transaction. Exit codes $0$ and $1$ indicate normal (successful) execution of the [compute phase](#compute). Exit (or [result](#action)) code $0$ indicates normal (successful) execution of the [action phase](#action). Any other exit code indicates that a certain exception has occurred and that the transaction wasn't successful in one way or another, i.e. transaction was reverted or the inbound message has bounced back. @@ -60,8 +62,8 @@ Exit code | Origin | Brief description [$133$](#133) | Tact compiler ([Compute phase][c]) | Contract stopped. Reserved, but never thrown. [$134$](#134) | Tact compiler ([Compute phase][c]) | Invalid argument. [$135$](#135) | Tact compiler ([Compute phase][c]) | Code of a contract was not found. -[$136$](#136) | Tact compiler ([Compute phase][c]) | Invalid address. -[$137$](#137) | Tact compiler ([Compute phase][c]) | Masterchain support is not enabled for this contract. +~~[$136$](#136)~~ | ~~Tact compiler ([Compute phase][c])~~ | ~~Invalid address.~~ Removed since Tact 1.6 +~~[$137$](#137)~~ | ~~Tact compiler ([Compute phase][c])~~ | ~~Masterchain support is not enabled for this contract.~~ Removed since Tact 1.6 :::note @@ -526,7 +528,7 @@ If the configuration is absent, default values are: * `ext_msg_limits.max_depth` is equal to $2^{9}$ — maximum external message [depth](/book/cells#cells-representation). * `max_acc_state_cells` is equal to $2^{16}$ — maximum number of [cells][cell] that an account state can occupy. * `max_acc_state_bits` is equal to $2^{16} * 1023$ — maximum account state size in bits. -* `max_acc_public_libraries` is equal to $2^{8}$ — maximum number of [library reference cells](/book/cells#cells-kinds) that an account state can use on the [masterchain](/book/masterchain). +* `max_acc_public_libraries` is equal to $2^{8}$ — maximum number of [library reference cells](/book/cells#cells-kinds) that an account state can use on the masterchain. * `defer_out_queue_size_limit` is equal to $2^{8}$ — maximum number of outbound messages to be queued (regards validators and collators). ## Tact compiler @@ -623,10 +625,12 @@ If the code of the contract doesn't match the one saved in TypeScript wrappers, ### 136: Invalid address {#136} +

+ A value of type [`Address{:tact}`][p] is valid in Tact when: * It occupies $267$ bits: $11$ bits for the chain ID prefix and $256$ bits for the [address itself](https://docs.ton.org/learn/overviews/addresses#address-of-smart-contract). -* It belongs to either: basechain (ID $0$) or masterchain (ID $-1$), with the latter requiring [masterchain support](/book/masterchain#support) to be enabled. +* It belongs to either basechain (ID $0$) or masterchain (ID $-1$). If the [`Address{:tact}`][p] isn't valid, the error with exit code $136$ will be thrown: `Invalid address`. @@ -644,7 +648,9 @@ try { ### 137: Masterchain support is not enabled for this contract {#137} -Any attempts to point to masterchain (ID $-1$) or otherwise interact with it without [enabling masterchain support](/book/masterchain#support) throw an exception with exit code $137$: `Masterchain support is not enabled for this contract`. +

+ +Prior to removal, any attempts to point to masterchain (ID $-1$) or otherwise interact with it without enabling masterchain support were throwing an exception with exit code $137$: `Masterchain support is not enabled for this contract`. ```tact let masterchainID = -1; diff --git a/docs/src/content/docs/book/masterchain.mdx b/docs/src/content/docs/book/masterchain.mdx deleted file mode 100644 index 76c209525..000000000 --- a/docs/src/content/docs/book/masterchain.mdx +++ /dev/null @@ -1,57 +0,0 @@ ---- -title: Masterchain -description: "In TON Blockchain, a special chain called masterchain is used to synchronize message routing and transaction execution, so that nodes in the network can fix a particular point in a multi-chain state and reach a consensus about that state" ---- - -:::caution - - Masterchain addresses are treated as invalid unless the `masterchain` option in the [configuration file](/book/config) is set to `true{:json}`. - -::: - -In TON Blockchain, a special chain called ["masterchain"](https://docs.ton.org/learn/overviews/ton-blockchain#masterchain-blockchain-of-blockchains) is used to synchronize message routing and transaction execution, so that nodes in the network can fix a particular point in a multi-chain state and reach a consensus about that state. - -Masterchain stores the [network configuration](/ref/core-advanced#getconfigparam) and the final state of all [workchains](https://docs.ton.org/learn/overviews/ton-blockchain#workchain-blockchain-with-your-own-rules). It carries fundamental protocol information, including current settings, a list of active validators and their stakes, active workchains, and associated [shardchains](https://docs.ton.org/develop/blockchain/shards). Most importantly, it maintains a record of the latest block hashes for all workchains and shardchains, enforcing consensus across the network. - -## How contract is protected from masterchain {#protection} - -Tact enforces all contracts to use the [basechain](https://docs.ton.org/develop/blockchain/shards), which is the default workchain with ID $0$. This is done to prevent masterchain addresses from being used in the contract. - -Any attempts to point to masterchain or otherwise interact with it without [enabling masterchain support](#support) throw an exception with [exit code 137](/book/exit-codes#137): `Masterchain support is not enabled for this contract`. - -That is, accidental deployments to the masterchain, receiving messages from masterchain accounts, sending messages to such accounts, and using masterchain addresses or its chain ID ($-1$) are all prohibited by default. - -## Enabling masterchain support in compilation options {#support} - -:::caution - -Most contracts don't need to be deployed on a masterchain or have any interactions on a masterchain. That's because the masterchain is primarily used for voting or storing libraries. If you don't need to partake in those things, you don't need to enable masterchain support. - -::: - -If you really do need masterchain support, the simplest and recommended approach is to modify a [`tact.config.json`](/book/config) file in the root of your project (or create it if it didn't exist yet), and [set the `masterchain` property to `true{:json}`](/book/config#options-masterchain). - -If you're working on a [Blueprint][bp]-based project, you can enable masterchain support in the compilation configs of your contracts, which are located in a directory named `wrappers/`: - -```typescript title="wrappers/YourContractName.compile.ts" {7} -import { CompilerConfig } from '@ton/blueprint'; - -export const compile: CompilerConfig = { - lang: 'tact', - target: 'contracts/your_contract_name.tact', - options: { - masterchain: true, // ← that's the stuff! - } -}; -``` - -However, [`tact.config.json`](/book/config) may still be used in [Blueprint][bp] projects. In such cases values specified in [`tact.config.json`](/book/config) act as default unless modified in the `wrappers/`. - -:::note - - If you have the `separateCompilables` option set to `true{:typescript}` in the [`blueprint.config.ts`][bp-config], then the `.compile.ts` files will be located in the `compilables/` directory and **not** in `wrappers/`. - -::: - -[bp]: https://github.com/ton-org/blueprint -[bp-config]: https://github.com/ton-org/blueprint/tree/main?tab=readme-ov-file#configuration diff --git a/docs/src/content/docs/ref/core-advanced.mdx b/docs/src/content/docs/ref/core-advanced.mdx index 25dba26cd..02531ef29 100644 --- a/docs/src/content/docs/ref/core-advanced.mdx +++ b/docs/src/content/docs/ref/core-advanced.mdx @@ -581,7 +581,7 @@ parsedVarAddr.address.loadUint(123); // 345 [int]: /book/integers [slice]: /book/cells#slices [s]: /book/structs-and-messages#structs -[masterchain]: /book/masterchain +[masterchain]: https://docs.ton.org/v3/documentation/smart-contracts/shards/shards-intro#masterchain [cell-hash]: /ref/core-cell#cellhash [nanotoncoin]: /book/integers#nanotoncoin diff --git a/docs/src/content/docs/ref/core-common.mdx b/docs/src/content/docs/ref/core-common.mdx index 64c28fdc3..4afcbf27e 100644 --- a/docs/src/content/docs/ref/core-common.mdx +++ b/docs/src/content/docs/ref/core-common.mdx @@ -138,7 +138,7 @@ let oldTonFoundationAddr: Address = :::caution - This method throws an error with [exit code 136](/book/exit-codes#136) if `chain` is invalid or with [exit code 137](/book/exit-codes#137) if `chain` points to the masterchain ($-1$) without [masterchain support](/book/masterchain) enabled. + Make sure your specify only supported chain IDs: $0$ for the basechain and $-1$ for the masterchain. ::: @@ -181,7 +181,7 @@ let hereBeDragons: Address = contractAddressExt(0, initPkg.code, initPkg.data); :::caution - This method throws an error with [exit code 136](/book/exit-codes#136) if `chain` is invalid or with [exit code 137](/book/exit-codes#137) if `chain` points to the masterchain ($-1$) without [masterchain support](/book/masterchain) enabled. + Make sure your specify only supported chain IDs: $0$ for the basechain and $-1$ for the masterchain. ::: diff --git a/docs/src/content/docs/zh-cn/book/contracts.mdx b/docs/src/content/docs/zh-cn/book/contracts.mdx index ff7d10718..63c4a2f7e 100644 --- a/docs/src/content/docs/zh-cn/book/contracts.mdx +++ b/docs/src/content/docs/zh-cn/book/contracts.mdx @@ -94,7 +94,6 @@ Tact 有一小套在特定条件下提供的接口: - `"org.ton.abi.ipfs.v0"{:tact}`,根据 [OTP-003: Self-ABI Reporting](/zh-cn/ref/evolution/otp-003) - 通过 [`ipfsAbiGetter`](/zh-cn/book/config#options-ipfsabigetter)配置属性选择加入 - `"org.ton.deploy.lazy.v0"{:tact}`,符合[OTP-005:参数可寻址合约](/zh-cn/ref/evolution/otp-005) - `"org.ton.debug.v0"{:tact}`,但只有在启用了[调试模式](/zh-cn/book/debug#debug-mode)时才会这样做 -- `"org.ton.chain.any.v0"{:tact}` 如果启用了 [masterchain](/zh-cn/book/masterchain) 支持,否则为 `"org.ton.chain.workchain.v0"{:tact}` [标准库](/zh-cn/ref/standard-libraries)中的一些[traits][trait]也定义了它们的接口: diff --git a/schemas/configSchema.json b/schemas/configSchema.json index 6cf6b5d21..7b627f50f 100644 --- a/schemas/configSchema.json +++ b/schemas/configSchema.json @@ -36,11 +36,6 @@ "default": false, "description": "False by default. If set to true, enables debug output of a contract and allows usage of `dump()` function, which is useful for debugging purposes. With this option enabled, the contract will report that it was compiled in debug mode using the supported_interfaces method.\n\nRead more on debugging Tact code: https://docs.tact-lang.org/book/debug." }, - "masterchain": { - "type": "boolean", - "default": false, - "description": "False by default. If set to true, enables masterchain support.\n\nRead more about masterchain: https://docs.tact-lang.org/book/masterchain." - }, "external": { "type": "boolean", "default": false, diff --git a/src/abi/errors.ts b/src/abi/errors.ts index ee04f2fc8..42d386d54 100644 --- a/src/abi/errors.ts +++ b/src/abi/errors.ts @@ -9,9 +9,4 @@ export const contractErrors = { contractStopped: { id: 133, message: "Contract stopped" }, invalidArgument: { id: 134, message: "Invalid argument" }, codeNotFound: { id: 135, message: "Code of a contract was not found" }, - invalidAddress: { id: 136, message: "Invalid address" }, - masterchainNotEnabled: { - id: 137, - message: "Masterchain support is not enabled for this contract", - }, }; diff --git a/src/abi/global.ts b/src/abi/global.ts index 86025f260..87ef019df 100644 --- a/src/abi/global.ts +++ b/src/abi/global.ts @@ -1,5 +1,5 @@ import { Address, beginCell, Cell, toNano } from "@ton/core"; -import { enabledDebug, enabledMasterchain } from "../config/features"; +import { enabledDebug } from "../config/features"; import { writeAddress, writeCell, @@ -163,14 +163,6 @@ export const GlobalFunctions: Map = new Map([ ref, ); } - if (!enabledMasterchain(ctx.ctx)) { - if (address.workChain !== 0) { - throwCompilationError( - `Address ${str} from masterchain are not enabled for this contract`, - ref, - ); - } - } // Generate address const res = writeAddress(address, ctx); diff --git a/src/benchmarks/benchmarks.spec.ts b/src/benchmarks/benchmarks.spec.ts index e82e88f79..6a9a80cd0 100644 --- a/src/benchmarks/benchmarks.spec.ts +++ b/src/benchmarks/benchmarks.spec.ts @@ -33,11 +33,11 @@ describe("benchmarks", () => { .description as TransactionDescriptionGeneric ).computePhase as TransactionComputeVm ).gasUsed; - expect(gasUsed).toMatchInlineSnapshot(`3648n`); + expect(gasUsed).toMatchInlineSnapshot(`3146n`); // Verify code size const codeSize = functions.init!.code.toBoc().length; - expect(codeSize).toMatchInlineSnapshot(`281`); + expect(codeSize).toMatchInlineSnapshot(`241`); }); it("benchmark functions (inline)", async () => { @@ -57,10 +57,10 @@ describe("benchmarks", () => { .description as TransactionDescriptionGeneric ).computePhase as TransactionComputeVm ).gasUsed; - expect(gasUsed).toMatchInlineSnapshot(`3517n`); + expect(gasUsed).toMatchInlineSnapshot(`3015n`); // Verify code size const codeSize = functionsInline.init!.code.toBoc().length; - expect(codeSize).toMatchInlineSnapshot(`274`); + expect(codeSize).toMatchInlineSnapshot(`234`); }); }); diff --git a/src/check.ts b/src/check.ts index 5bc55e948..27584a5e0 100644 --- a/src/check.ts +++ b/src/check.ts @@ -34,7 +34,6 @@ export function check(args: { const stdlib = createVirtualFileSystem("@stdlib/", files); let ctx: CompilerContext = new CompilerContext(); ctx = featureEnable(ctx, "debug"); // Enable debug flag (does not affect type checking in practice) - ctx = featureEnable(ctx, "masterchain"); // Enable masterchain flag to avoid masterchain-specific errors ctx = featureEnable(ctx, "external"); // Enable external messages flag to avoid external-specific errors const ast = getAstFactory(); diff --git a/src/config/features.ts b/src/config/features.ts index 4d8a9d0af..1b9cc5a14 100644 --- a/src/config/features.ts +++ b/src/config/features.ts @@ -10,10 +10,6 @@ export function enabledDebug(ctx: CompilerContext) { return featureEnabled(ctx, "debug"); } -export function enabledMasterchain(ctx: CompilerContext) { - return featureEnabled(ctx, "masterchain"); -} - export function enabledExternals(ctx: CompilerContext) { return featureEnabled(ctx, "external"); } diff --git a/src/config/parseConfig.ts b/src/config/parseConfig.ts index f4633b186..1aa303f45 100644 --- a/src/config/parseConfig.ts +++ b/src/config/parseConfig.ts @@ -9,12 +9,6 @@ export const optionsSchema = z * Read more: https://docs.tact-lang.org/book/debug */ debug: z.boolean().optional(), - /** - * If set to true, enables masterchain support. - * - * Read more: https://docs.tact-lang.org/book/masterchain - */ - masterchain: z.boolean().optional(), /** * If set to true, enables support of external message receivers. * diff --git a/src/generator/writers/__snapshots__/writeSerialization.spec.ts.snap b/src/generator/writers/__snapshots__/writeSerialization.spec.ts.snap index 30db3674f..10b4a432c 100644 --- a/src/generator/writers/__snapshots__/writeSerialization.spec.ts.snap +++ b/src/generator/writers/__snapshots__/writeSerialization.spec.ts.snap @@ -57,36 +57,15 @@ exports[`writeSerialization should write serializer for A 1`] = ` "name": "__tact_address_to_slice", "signature": "", }, - { - "code": { - "code": "throw_unless(136, address.slice_bits() == 267); -var h = address.preload_uint(11); -throw_if(137, h == 1279); -throw_unless(136, h == 1024); -return address;", - "kind": "generic", - }, - "comment": null, - "context": "stdlib", - "depends": Set {}, - "flags": Set { - "impure", - "inline", - }, - "name": "__tact_verify_address", - "signature": "slice __tact_verify_address(slice address)", - }, { "code": { "code": "slice raw = cs~load_msg_addr(); -return (cs, __tact_verify_address(raw));", +return (cs, raw);", "kind": "generic", }, "comment": null, "context": "stdlib", - "depends": Set { - "__tact_verify_address", - }, + "depends": Set {}, "flags": Set { "inline", }, @@ -97,7 +76,7 @@ return (cs, __tact_verify_address(raw));", "code": { "code": "if (cs.preload_uint(2) != 0) { slice raw = cs~load_msg_addr(); - return (cs, __tact_verify_address(raw)); + return (cs, raw); } else { cs~skip_bits(2); return (cs, null()); @@ -106,9 +85,7 @@ return (cs, __tact_verify_address(raw));", }, "comment": null, "context": "stdlib", - "depends": Set { - "__tact_verify_address", - }, + "depends": Set {}, "flags": Set { "inline", }, @@ -117,14 +94,12 @@ return (cs, __tact_verify_address(raw));", }, { "code": { - "code": "return b.store_slice(__tact_verify_address(address));", + "code": "return b.store_slice(address);", "kind": "generic", }, "comment": null, "context": "stdlib", - "depends": Set { - "__tact_verify_address", - }, + "depends": Set {}, "flags": Set { "inline", }, @@ -160,14 +135,12 @@ b = b.store_uint(0, 1); b = b.store_int(chain, 8); b = b.store_uint(hash, 256); var addr = b.end_cell().begin_parse(); -return __tact_verify_address(addr);", +return addr;", "kind": "generic", }, "comment": null, "context": "stdlib", - "depends": Set { - "__tact_verify_address", - }, + "depends": Set {}, "flags": Set { "inline", }, @@ -4318,13 +4291,12 @@ return $C$_to_tuple($C$_not_null(v)); ", { "code": { "code": "var (cell v'a, cell v'b, slice v'c, slice v'd, int v'e, int v'f, int v'g, slice v'h) = __tact_tuple_destroy_8(v); -return (v'a, v'b, v'c, v'd, v'e, v'f, v'g, __tact_verify_address(v'h));", +return (v'a, v'b, v'c, v'd, v'e, v'f, v'g, v'h);", "kind": "generic", }, "comment": null, "context": "type:C", "depends": Set { - "__tact_verify_address", "__tact_tuple_destroy_8", }, "flags": Set { @@ -4483,36 +4455,15 @@ exports[`writeSerialization should write serializer for B 1`] = ` "name": "__tact_address_to_slice", "signature": "", }, - { - "code": { - "code": "throw_unless(136, address.slice_bits() == 267); -var h = address.preload_uint(11); -throw_if(137, h == 1279); -throw_unless(136, h == 1024); -return address;", - "kind": "generic", - }, - "comment": null, - "context": "stdlib", - "depends": Set {}, - "flags": Set { - "impure", - "inline", - }, - "name": "__tact_verify_address", - "signature": "slice __tact_verify_address(slice address)", - }, { "code": { "code": "slice raw = cs~load_msg_addr(); -return (cs, __tact_verify_address(raw));", +return (cs, raw);", "kind": "generic", }, "comment": null, "context": "stdlib", - "depends": Set { - "__tact_verify_address", - }, + "depends": Set {}, "flags": Set { "inline", }, @@ -4523,7 +4474,7 @@ return (cs, __tact_verify_address(raw));", "code": { "code": "if (cs.preload_uint(2) != 0) { slice raw = cs~load_msg_addr(); - return (cs, __tact_verify_address(raw)); + return (cs, raw); } else { cs~skip_bits(2); return (cs, null()); @@ -4532,9 +4483,7 @@ return (cs, __tact_verify_address(raw));", }, "comment": null, "context": "stdlib", - "depends": Set { - "__tact_verify_address", - }, + "depends": Set {}, "flags": Set { "inline", }, @@ -4543,14 +4492,12 @@ return (cs, __tact_verify_address(raw));", }, { "code": { - "code": "return b.store_slice(__tact_verify_address(address));", + "code": "return b.store_slice(address);", "kind": "generic", }, "comment": null, "context": "stdlib", - "depends": Set { - "__tact_verify_address", - }, + "depends": Set {}, "flags": Set { "inline", }, @@ -4586,14 +4533,12 @@ b = b.store_uint(0, 1); b = b.store_int(chain, 8); b = b.store_uint(hash, 256); var addr = b.end_cell().begin_parse(); -return __tact_verify_address(addr);", +return addr;", "kind": "generic", }, "comment": null, "context": "stdlib", - "depends": Set { - "__tact_verify_address", - }, + "depends": Set {}, "flags": Set { "inline", }, @@ -8744,13 +8689,12 @@ return $C$_to_tuple($C$_not_null(v)); ", { "code": { "code": "var (cell v'a, cell v'b, slice v'c, slice v'd, int v'e, int v'f, int v'g, slice v'h) = __tact_tuple_destroy_8(v); -return (v'a, v'b, v'c, v'd, v'e, v'f, v'g, __tact_verify_address(v'h));", +return (v'a, v'b, v'c, v'd, v'e, v'f, v'g, v'h);", "kind": "generic", }, "comment": null, "context": "type:C", "depends": Set { - "__tact_verify_address", "__tact_tuple_destroy_8", }, "flags": Set { @@ -8909,36 +8853,15 @@ exports[`writeSerialization should write serializer for C 1`] = ` "name": "__tact_address_to_slice", "signature": "", }, - { - "code": { - "code": "throw_unless(136, address.slice_bits() == 267); -var h = address.preload_uint(11); -throw_if(137, h == 1279); -throw_unless(136, h == 1024); -return address;", - "kind": "generic", - }, - "comment": null, - "context": "stdlib", - "depends": Set {}, - "flags": Set { - "impure", - "inline", - }, - "name": "__tact_verify_address", - "signature": "slice __tact_verify_address(slice address)", - }, { "code": { "code": "slice raw = cs~load_msg_addr(); -return (cs, __tact_verify_address(raw));", +return (cs, raw);", "kind": "generic", }, "comment": null, "context": "stdlib", - "depends": Set { - "__tact_verify_address", - }, + "depends": Set {}, "flags": Set { "inline", }, @@ -8949,7 +8872,7 @@ return (cs, __tact_verify_address(raw));", "code": { "code": "if (cs.preload_uint(2) != 0) { slice raw = cs~load_msg_addr(); - return (cs, __tact_verify_address(raw)); + return (cs, raw); } else { cs~skip_bits(2); return (cs, null()); @@ -8958,9 +8881,7 @@ return (cs, __tact_verify_address(raw));", }, "comment": null, "context": "stdlib", - "depends": Set { - "__tact_verify_address", - }, + "depends": Set {}, "flags": Set { "inline", }, @@ -8969,14 +8890,12 @@ return (cs, __tact_verify_address(raw));", }, { "code": { - "code": "return b.store_slice(__tact_verify_address(address));", + "code": "return b.store_slice(address);", "kind": "generic", }, "comment": null, "context": "stdlib", - "depends": Set { - "__tact_verify_address", - }, + "depends": Set {}, "flags": Set { "inline", }, @@ -9012,14 +8931,12 @@ b = b.store_uint(0, 1); b = b.store_int(chain, 8); b = b.store_uint(hash, 256); var addr = b.end_cell().begin_parse(); -return __tact_verify_address(addr);", +return addr;", "kind": "generic", }, "comment": null, "context": "stdlib", - "depends": Set { - "__tact_verify_address", - }, + "depends": Set {}, "flags": Set { "inline", }, @@ -13173,13 +13090,12 @@ return $C$_to_tuple($C$_not_null(v)); ", { "code": { "code": "var (cell v'a, cell v'b, slice v'c, slice v'd, int v'e, int v'f, int v'g, slice v'h) = __tact_tuple_destroy_8(v); -return (v'a, v'b, v'c, v'd, v'e, v'f, v'g, __tact_verify_address(v'h));", +return (v'a, v'b, v'c, v'd, v'e, v'f, v'g, v'h);", "kind": "generic", }, "comment": null, "context": "type:C", "depends": Set { - "__tact_verify_address", "__tact_tuple_destroy_8", }, "flags": Set { diff --git a/src/generator/writers/writeAccessors.ts b/src/generator/writers/writeAccessors.ts index 191235f59..dab34430f 100644 --- a/src/generator/writers/writeAccessors.ts +++ b/src/generator/writers/writeAccessors.ts @@ -212,21 +212,10 @@ export function writeAccessors( t.kind === "primitive_type_decl" && t.name === "Address" ) { - if (f.type.optional) { - vars.push( - `${resolveFuncType(f.type, ctx)} v'${f.name}`, - ); - out.push( - `null?(v'${f.name}) ? null() : ${ctx.used(`__tact_verify_address`)}(v'${f.name})`, - ); - } else { - vars.push( - `${resolveFuncType(f.type, ctx)} v'${f.name}`, - ); - out.push( - `${ctx.used(`__tact_verify_address`)}(v'${f.name})`, - ); - } + vars.push( + `${resolveFuncType(f.type, ctx)} v'${f.name}`, + ); + out.push(`v'${f.name}`); continue; } } diff --git a/src/generator/writers/writeContract.ts b/src/generator/writers/writeContract.ts index 4cf60f77f..14264c06a 100644 --- a/src/generator/writers/writeContract.ts +++ b/src/generator/writers/writeContract.ts @@ -3,7 +3,6 @@ import { enabledInline, enabledInterfacesGetter, enabledIpfsAbiGetter, - enabledMasterchain, } from "../../config/features"; import { ItemOrigin } from "../../grammar"; import { InitDescription, TypeDescription } from "../../types/types"; @@ -50,14 +49,6 @@ export function writeStorageOps( }); ctx.append(`} else {`); ctx.inIndent(() => { - // Allow only workchain deployments - if (!enabledMasterchain(ctx.ctx)) { - ctx.write(`;; Allow only workchain deployments`); - ctx.write( - `throw_unless(${contractErrors.masterchainNotEnabled.id}, my_address().preload_uint(11) == 1024);`, - ); - } - // Load arguments if (type.init!.params.length > 0) { ctx.append( @@ -305,9 +296,7 @@ export function writeMainContract( ctx.append(`var cs = in_msg_cell.begin_parse();`); ctx.append(`var msg_flags = cs~load_uint(4);`); // int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool ctx.append(`var msg_bounced = -(msg_flags & 1);`); - ctx.append( - `slice msg_sender_addr = ${ctx.used("__tact_verify_address")}(cs~load_msg_addr());`, - ); + ctx.append(`slice msg_sender_addr = cs~load_msg_addr();`); ctx.append( `__tact_context = (msg_bounced, msg_sender_addr, msg_value, cs);`, ); diff --git a/src/generator/writers/writeFunction.ts b/src/generator/writers/writeFunction.ts index 88c3fc51c..a5536b642 100644 --- a/src/generator/writers/writeFunction.ts +++ b/src/generator/writers/writeFunction.ts @@ -54,15 +54,9 @@ function unwrapExternal( } return; } else if (t.kind === "primitive_type_decl" && t.name === "Address") { - if (type.optional) { - ctx.append( - `${resolveFuncType(type, ctx)} ${targetName} = null?(${sourceName}) ? null() : ${ctx.used(`__tact_verify_address`)}(${sourceName});`, - ); - } else { - ctx.append( - `${resolveFuncType(type, ctx)} ${targetName} = ${ctx.used(`__tact_verify_address`)}(${sourceName});`, - ); - } + ctx.append( + `${resolveFuncType(type, ctx)} ${targetName} = ${sourceName};`, + ); return; } } diff --git a/src/generator/writers/writeStdlib.ts b/src/generator/writers/writeStdlib.ts index 4bd365603..13e06f807 100644 --- a/src/generator/writers/writeStdlib.ts +++ b/src/generator/writers/writeStdlib.ts @@ -1,6 +1,5 @@ import { contractErrors } from "../../abi/errors"; import { maxTupleSize } from "../../bindings/typescript/writeStruct"; -import { enabledMasterchain } from "../../config/features"; import { match } from "../../utils/tricks"; import { WriterContext } from "../Writer"; @@ -19,33 +18,6 @@ export function writeStdlib(ctx: WriterContext): void { // Addresses // - ctx.fun("__tact_verify_address", () => { - ctx.signature(`slice __tact_verify_address(slice address)`); - ctx.flag("impure"); - ctx.flag("inline"); - ctx.context("stdlib"); - ctx.body(() => { - ctx.write(` - throw_unless(${contractErrors.invalidAddress.id}, address.slice_bits() == 267); - var h = address.preload_uint(11); - `); - - if (enabledMasterchain(ctx.ctx)) { - ctx.write(` - throw_unless(${contractErrors.invalidAddress.id}, (h == 1024) | (h == 1279)); - `); - } else { - ctx.write(` - throw_if(${contractErrors.masterchainNotEnabled.id}, h == 1279); - throw_unless(${contractErrors.invalidAddress.id}, h == 1024); - `); - } - ctx.write(` - return address; - `); - }); - }); - ctx.fun("__tact_load_address", () => { ctx.signature(`(slice, slice) __tact_load_address(slice cs)`); ctx.flag("inline"); @@ -53,7 +25,7 @@ export function writeStdlib(ctx: WriterContext): void { ctx.body(() => { ctx.write(` slice raw = cs~load_msg_addr(); - return (cs, ${ctx.used(`__tact_verify_address`)}(raw)); + return (cs, raw); `); }); }); @@ -66,7 +38,7 @@ export function writeStdlib(ctx: WriterContext): void { ctx.write(` if (cs.preload_uint(2) != 0) { slice raw = cs~load_msg_addr(); - return (cs, ${ctx.used(`__tact_verify_address`)}(raw)); + return (cs, raw); } else { cs~skip_bits(2); return (cs, null()); @@ -81,9 +53,7 @@ export function writeStdlib(ctx: WriterContext): void { ctx.context("stdlib"); ctx.body(() => { ctx.write(` - return b.store_slice(${ctx.used( - `__tact_verify_address`, - )}(address)); + return b.store_slice(address); `); }); }); @@ -118,7 +88,7 @@ export function writeStdlib(ctx: WriterContext): void { b = b.store_int(chain, 8); b = b.store_uint(hash, 256); var addr = b.end_cell().begin_parse(); - return ${ctx.used(`__tact_verify_address`)}(addr); + return addr; `); }); }); diff --git a/src/interpreter.ts b/src/interpreter.ts index e81a1e1ab..2b9268cab 100644 --- a/src/interpreter.ts +++ b/src/interpreter.ts @@ -74,7 +74,6 @@ import { showValue, } from "./types/types"; import { sha256_sync } from "@ton/crypto"; -import { enabledMasterchain } from "./config/features"; // TVM integers are signed 257-bit integers const minTvmInt: bigint = -(2n ** 256n); @@ -1228,15 +1227,6 @@ export class Interpreter { ast.loc, ); } - if ( - !enabledMasterchain(this.context) && - address.workChain !== 0 - ) { - throwErrorConstEval( - `address ${str} is from masterchain which is not enabled for this contract`, - ast.loc, - ); - } return address; } catch (_) { throwErrorConstEval( @@ -1267,12 +1257,6 @@ export class Interpreter { ast.loc, ); } - if (!enabledMasterchain(this.context) && wc !== 0n) { - throwErrorConstEval( - `${wc}:${addr.toString("hex")} address is from masterchain which is not enabled for this contract`, - ast.loc, - ); - } return new Address(Number(wc), addr); } default: diff --git a/src/pipeline/build.ts b/src/pipeline/build.ts index f892003ca..0188a7068 100644 --- a/src/pipeline/build.ts +++ b/src/pipeline/build.ts @@ -33,7 +33,6 @@ export function enableFeatures( } const features = [ { option: config.options.debug, name: "debug" }, - { option: config.options.masterchain, name: "masterchain" }, { option: config.options.external, name: "external" }, { option: config.options.experimental?.inline, name: "inline" }, { option: config.options.ipfsAbiGetter, name: "ipfsAbiGetter" }, diff --git a/src/test/e2e-emulated/__snapshots__/local-type-inference.spec.ts.snap b/src/test/e2e-emulated/__snapshots__/local-type-inference.spec.ts.snap index 5573c4ad8..b532d1103 100644 --- a/src/test/e2e-emulated/__snapshots__/local-type-inference.spec.ts.snap +++ b/src/test/e2e-emulated/__snapshots__/local-type-inference.spec.ts.snap @@ -39,12 +39,6 @@ exports[`local-type-inference should automatically set types for let statements "135": { "message": "Code of a contract was not found", }, - "136": { - "message": "Invalid address", - }, - "137": { - "message": "Masterchain support is not enabled for this contract", - }, "14": { "message": "Virtualization error", }, diff --git a/src/test/e2e-emulated/contracts/masterchain.tact b/src/test/e2e-emulated/contracts/masterchain.tact index eb9df01a7..37eae878c 100644 --- a/src/test/e2e-emulated/contracts/masterchain.tact +++ b/src/test/e2e-emulated/contracts/masterchain.tact @@ -1,6 +1,19 @@ -message TestMessage { - address: Address; - address2: Address?; +// not reusing previously used 136 and 137 exit codes +// because Tact reserves the codes from 128 to 255 +// and now this is user-land checks +const InvalidAddressExitCode: Int = 1136; +const MasterchainNotEnabled: Int = 1137; + +fun verifyAddress(addr: Address, enabledMasterChain: Bool) { + let addrSlice = addr.asSlice(); + nativeThrowUnless(InvalidAddressExitCode, addrSlice.bits() == 267); + let h = addrSlice.preloadUint(11); + if (enabledMasterChain) { + nativeThrowUnless(InvalidAddressExitCode, (h == 1024) || (h == 1279)); + } else { + nativeThrowIf(MasterchainNotEnabled, h == 1279); + nativeThrowUnless(InvalidAddressExitCode, h == 1024); + } } contract MasterchainTester { @@ -9,27 +22,11 @@ contract MasterchainTester { } - receive("Deploy") { - // Deploy - } - - receive(message: TestMessage) { - // Should fail for non-masterchain - } - - get fun createAddress(chain: Int, hash: Int): Address { - return newAddress(chain, hash); + receive("DeployToWorkchain") { + verifyAddress(sender(), false); } - get fun parseAddress(src: Slice): Address { - return src.loadAddress(); + receive("DeployToMasterchain") { + verifyAddress(sender(), true); } - - get fun serializeAddress(src: Address): Bool { - return true; // NOTE: src is unused but still have to be checked - } - - get fun handleStruct(src: TestMessage): Bool { - return true; // NOTE: src is unused but still have to be checked - } -} \ No newline at end of file +} diff --git a/src/test/e2e-emulated/masterchain.spec.ts b/src/test/e2e-emulated/masterchain.spec.ts index 40a50a961..a351dd5ee 100644 --- a/src/test/e2e-emulated/masterchain.spec.ts +++ b/src/test/e2e-emulated/masterchain.spec.ts @@ -1,7 +1,6 @@ -import { Address, beginCell, toNano } from "@ton/core"; +import { toNano } from "@ton/core"; import { Blockchain, SandboxContract, TreasuryContract } from "@ton/sandbox"; import { MasterchainTester } from "./contracts/output/masterchain_MasterchainTester"; -import { MasterchainTester as EnabledTester } from "./contracts/output/masterchain-allow_MasterchainTester"; import "@ton/test-utils"; describe("masterchain", () => { @@ -18,7 +17,7 @@ describe("masterchain", () => { // Deployment and simple message receiving // - it("should deploy to the workchain", async () => { + it("should deploy to workchain", async () => { const contract = blockchain.openContract( await MasterchainTester.fromInit(), ); @@ -26,7 +25,7 @@ describe("masterchain", () => { const deployResult = await contract.send( treasure.getSender(), { value: toNano("10") }, - "Deploy", + "DeployToWorkchain", ); expect(deployResult.transactions).toHaveTransaction({ @@ -37,26 +36,7 @@ describe("masterchain", () => { }); }); - it("should deploy to the workchain when masterchain enabled", async () => { - const contract = blockchain.openContract( - await EnabledTester.fromInit(), - ); - - const deployResult = await contract.send( - treasure.getSender(), - { value: toNano("10") }, - "Deploy", - ); - - expect(deployResult.transactions).toHaveTransaction({ - from: treasure.address, - to: contract.address, - success: true, - deploy: true, - }); - }); - - it("should not deploy to the workchain from masterchain", async () => { + it("should not deploy to workchain from masterchain", async () => { const treasure = await blockchain.treasury("treasure", { workchain: -1, }); @@ -67,7 +47,7 @@ describe("masterchain", () => { const deployResult = await contract.send( treasure.getSender(), { value: toNano("10") }, - "Deploy", + "DeployToWorkchain", ); expect(deployResult.transactions).toHaveTransaction({ @@ -75,22 +55,22 @@ describe("masterchain", () => { to: contract.address, success: false, deploy: true, - exitCode: 137, + exitCode: 1137, }); }); - it("should deploy to the workchain from masterchain when masterchain enabled", async () => { + it("should deploy to masterchain from masterchain", async () => { const treasure = await blockchain.treasury("treasure", { workchain: -1, }); const contract = blockchain.openContract( - await EnabledTester.fromInit(), + await MasterchainTester.fromInit(), ); const deployResult = await contract.send( treasure.getSender(), { value: toNano("10") }, - "Deploy", + "DeployToMasterchain", ); expect(deployResult.transactions).toHaveTransaction({ @@ -100,323 +80,4 @@ describe("masterchain", () => { deploy: true, }); }); - - // - // newAddress - // - - it("should create address for the workchain", async () => { - const contract = blockchain.openContract( - await MasterchainTester.fromInit(), - ); - - await contract.send( - treasure.getSender(), - { value: toNano("10") }, - "Deploy", - ); - - const address = await contract.getCreateAddress(0n, 0n); - expect(address).toBeDefined(); - }); - - it("should not create address for the masterchain", async () => { - const contract = blockchain.openContract( - await MasterchainTester.fromInit(), - ); - - await contract.send( - treasure.getSender(), - { value: toNano("10") }, - "Deploy", - ); - - await expect(contract.getCreateAddress(-1n, 0n)).rejects.toThrow( - "Unable to execute get method. Got exit_code: 137", - ); - }); - - it("should create address for the masterchain when masterchain enabled", async () => { - const contract = blockchain.openContract( - await EnabledTester.fromInit(), - ); - - await contract.send( - treasure.getSender(), - { value: toNano("10") }, - "Deploy", - ); - - const address = await contract.getCreateAddress(-1n, 0n); - expect(address).toBeDefined(); - }); - - it("should not create address for invalid workchain", async () => { - const contract = blockchain.openContract( - await MasterchainTester.fromInit(), - ); - - await contract.send( - treasure.getSender(), - { value: toNano("10") }, - "Deploy", - ); - - await expect(contract.getCreateAddress(10n, 0n)).rejects.toThrow( - "Unable to execute get method. Got exit_code: 136", - ); - }); - - // - // loadAddress - // - - it("should load address for the workchain", async () => { - const contract = blockchain.openContract( - await MasterchainTester.fromInit(), - ); - - await contract.send( - treasure.getSender(), - { value: toNano("10") }, - "Deploy", - ); - - const addr = new Address(0, Buffer.alloc(32, 0)); - expect( - ( - await contract.getParseAddress( - beginCell().storeAddress(addr).endCell().asSlice(), - ) - ).equals(addr), - ).toBe(true); - }); - - it("should not load address for the masterchain", async () => { - const contract = blockchain.openContract( - await MasterchainTester.fromInit(), - ); - - await contract.send( - treasure.getSender(), - { value: toNano("10") }, - "Deploy", - ); - - const addr = new Address(-1, Buffer.alloc(32, 0)); - await expect( - contract.getParseAddress( - beginCell().storeAddress(addr).endCell().asSlice(), - ), - ).rejects.toThrowError( - "Unable to execute get method. Got exit_code: 137", - ); - }); - - it("should load address for the workchain when masterchain enabled", async () => { - const contract = blockchain.openContract( - await EnabledTester.fromInit(), - ); - - await contract.send( - treasure.getSender(), - { value: toNano("10") }, - "Deploy", - ); - - const addr = new Address(0, Buffer.alloc(32, 0)); - expect( - ( - await contract.getParseAddress( - beginCell().storeAddress(addr).endCell().asSlice(), - ) - ).equals(addr), - ).toBe(true); - }); - - it("should load address for the masterchain when masterchain enabled", async () => { - const contract = blockchain.openContract( - await EnabledTester.fromInit(), - ); - - await contract.send( - treasure.getSender(), - { value: toNano("10") }, - "Deploy", - ); - - const addr = new Address(-1, Buffer.alloc(32, 0)); - expect( - ( - await contract.getParseAddress( - beginCell().storeAddress(addr).endCell().asSlice(), - ) - ).equals(addr), - ).toBe(true); - }); - - // - // argument of get method - // - - it("should handle address in get argument for the workchain", async () => { - const contract = blockchain.openContract( - await MasterchainTester.fromInit(), - ); - - await contract.send( - treasure.getSender(), - { value: toNano("10") }, - "Deploy", - ); - - const addr = new Address(0, Buffer.alloc(32, 0)); - await contract.getSerializeAddress(addr); - }); - - it("should not handle address in get argument for the masterchain", async () => { - const contract = blockchain.openContract( - await MasterchainTester.fromInit(), - ); - - await contract.send( - treasure.getSender(), - { value: toNano("10") }, - "Deploy", - ); - - const addr = new Address(-1, Buffer.alloc(32, 0)); - await expect(contract.getSerializeAddress(addr)).rejects.toThrowError( - "Unable to execute get method. Got exit_code: 137", - ); - }); - - it("should handle address in get argument for the workchain when masterchain enabled", async () => { - const contract = blockchain.openContract( - await EnabledTester.fromInit(), - ); - - await contract.send( - treasure.getSender(), - { value: toNano("10") }, - "Deploy", - ); - - const addr = new Address(0, Buffer.alloc(32, 0)); - await contract.getSerializeAddress(addr); - }); - - it("should handle address in get argument for the masterchain when masterchain enabled", async () => { - const contract = blockchain.openContract( - await EnabledTester.fromInit(), - ); - - await contract.send( - treasure.getSender(), - { value: toNano("10") }, - "Deploy", - ); - - const addr = new Address(-1, Buffer.alloc(32, 0)); - await contract.getSerializeAddress(addr); - }); - - // - // argument of get method in struct - // - - it("should handle address in get argument struct for the workchain", async () => { - const contract = blockchain.openContract( - await MasterchainTester.fromInit(), - ); - - await contract.send( - treasure.getSender(), - { value: toNano("10") }, - "Deploy", - ); - - const addr = new Address(0, Buffer.alloc(32, 0)); - await contract.getHandleStruct({ - $$type: "TestMessage", - address: addr, - address2: null, - }); - await contract.getHandleStruct({ - $$type: "TestMessage", - address: addr, - address2: addr, - }); - }); - - it("should not handle address in get argument struct for the masterchain", async () => { - const contract = blockchain.openContract( - await MasterchainTester.fromInit(), - ); - - await contract.send( - treasure.getSender(), - { value: toNano("10") }, - "Deploy", - ); - - const addr = new Address(-1, Buffer.alloc(32, 0)); - const addr2 = new Address(0, Buffer.alloc(32, 0)); - await expect( - contract.getHandleStruct({ - $$type: "TestMessage", - address: addr, - address2: null, - }), - ).rejects.toThrowError( - "Unable to execute get method. Got exit_code: 137", - ); - await expect( - contract.getHandleStruct({ - $$type: "TestMessage", - address: addr2, - address2: addr, - }), - ).rejects.toThrowError( - "Unable to execute get method. Got exit_code: 137", - ); - }); - - it("should handle address in get argument struct for the workchain when masterchain enabled", async () => { - const contract = blockchain.openContract( - await EnabledTester.fromInit(), - ); - - await contract.send( - treasure.getSender(), - { value: toNano("10") }, - "Deploy", - ); - - const addr = new Address(0, Buffer.alloc(32, 0)); - await contract.getHandleStruct({ - $$type: "TestMessage", - address: addr, - address2: addr, - }); - }); - - it("should handle address in get argument struct for the masterchain when masterchain enabled", async () => { - const contract = blockchain.openContract( - await EnabledTester.fromInit(), - ); - - await contract.send( - treasure.getSender(), - { value: toNano("10") }, - "Deploy", - ); - - const addr = new Address(-1, Buffer.alloc(32, 0)); - await contract.getHandleStruct({ - $$type: "TestMessage", - address: addr, - address2: addr, - }); - }); }); diff --git a/src/test/exit-codes/contracts/tact-reserved-contract-errors.tact b/src/test/exit-codes/contracts/tact-reserved-contract-errors.tact index f4498f444..2d569f951 100644 --- a/src/test/exit-codes/contracts/tact-reserved-contract-errors.tact +++ b/src/test/exit-codes/contracts/tact-reserved-contract-errors.tact @@ -96,22 +96,4 @@ contract ReservedContractErrorsTester with Ownable { // so let's throw it explicitly now for the tests on Blueprint's side throw(targetCode); } - - /// Exit code 136 - receive("136") { - let unsupportedChainId = 1; - dump( - // Zero address in unsupported workchain - newAddress(unsupportedChainId, 0) - ); - } - - /// Exit code 137 - receive("137") { - let masterchainId = -1; - dump( - // Zero address in masterchain without the config option set - newAddress(masterchainId, 0) - ); - } } diff --git a/src/test/exit-codes/tact-reserved-contract-errors.spec.ts b/src/test/exit-codes/tact-reserved-contract-errors.spec.ts index d29ecddff..a1f035618 100644 --- a/src/test/exit-codes/tact-reserved-contract-errors.spec.ts +++ b/src/test/exit-codes/tact-reserved-contract-errors.spec.ts @@ -64,16 +64,6 @@ describe("Tact-reserved contract errors", () => { // 135: Code of a contract was not found // NOTE: Reserved, but one has to replace the contract code to trigger it - - // 136: Invalid address - it("should test exit code 136", async () => { - await testReservedExitCode(136, contract, treasure); - }); - - // 137: Masterchain support is not enabled for this contract - it("should test exit code 137", async () => { - await testReservedExitCode(137, contract, treasure); - }); }); async function testReservedExitCode( @@ -83,8 +73,8 @@ async function testReservedExitCode( ) { expect(code).toBeGreaterThanOrEqual(128); expect(code).toBeLessThan(256); - expect([128, 130, 132, 134, 136, 137]).toContain(code); - type testedExitCodes = "128" | "130" | "132" | "134" | "136" | "137"; + expect([128, 130, 132, 134]).toContain(code); + type testedExitCodes = "128" | "130" | "132" | "134"; const sendResult = await contract.send( treasure.getSender(), diff --git a/src/types/getSupportedInterfaces.ts b/src/types/getSupportedInterfaces.ts index 0f5cd639e..2ac15702f 100644 --- a/src/types/getSupportedInterfaces.ts +++ b/src/types/getSupportedInterfaces.ts @@ -1,4 +1,4 @@ -import { enabledDebug, enabledMasterchain } from "../config/features"; +import { enabledDebug } from "../config/features"; import { CompilerContext } from "../context"; import { TypeDescription } from "./types"; @@ -12,11 +12,6 @@ export function getSupportedInterfaces( if (enabledDebug(ctx)) { interfaces.push("org.ton.debug.v0"); } - if (!enabledMasterchain(ctx)) { - interfaces.push("org.ton.chain.workchain.v0"); - } else { - interfaces.push("org.ton.chain.any.v0"); - } type.interfaces.forEach((iface) => interfaces.push(iface)); return interfaces; } diff --git a/tact.config.json b/tact.config.json index 26d48232a..cad08c5fa 100644 --- a/tact.config.json +++ b/tact.config.json @@ -109,8 +109,7 @@ "path": "./src/test/e2e-emulated/contracts/optionals.tact", "output": "./src/test/e2e-emulated/contracts/output", "options": { - "debug": true, - "masterchain": true + "debug": true } }, { @@ -262,15 +261,6 @@ "path": "./src/test/e2e-emulated/contracts/try-catch.tact", "output": "./src/test/e2e-emulated/contracts/output" }, - { - "name": "masterchain-allow", - "path": "./src/test/e2e-emulated/contracts/masterchain.tact", - "output": "./src/test/e2e-emulated/contracts/output", - "options": { - "debug": true, - "masterchain": true - } - }, { "name": "address", "path": "./src/test/e2e-emulated/contracts/address.tact",