From da6a7f6e3eb56a20f5daafa84e50d095f923f3ba Mon Sep 17 00:00:00 2001 From: 0kenx Date: Wed, 5 Jun 2024 16:54:11 +0200 Subject: [PATCH] fix: `__tact_load_address_opt` (#370) (#373) --- CHANGELOG.md | 1 + .../writeSerialization.spec.ts.snap | 15 ++++++----- src/generator/writers/writeStdlib.ts | 5 ++-- src/test/__snapshots__/bugs.spec.ts.snap | 8 +++--- .../feature-masterchain.spec.ts.snap | 10 ++++---- src/test/feature-optionals.spec.ts | 22 ++++++++++++++++ src/test/features/optionals-2.tact | 25 ++++++++++++++++++- 7 files changed, 68 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c3e474db0..b8e5e0b77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - All identifiers in error messages are now quoted for consistency: PR [#363](https://github.com/tact-lang/tact/pull/363) - The grammar of the unary operators has been fixed, constant and function declarations are prohibited for contracts and at the top level of Tact modules: PR [#365](https://github.com/tact-lang/tact/pull/365) - Typos in ABI generation: : PR [#372](https://github.com/tact-lang/tact/pull/372) +- `__tact_load_address_opt` code generation: PR [#373](https://github.com/tact-lang/tact/pull/373) ## [1.3.0] - 2024-05-03 diff --git a/src/generator/writers/__snapshots__/writeSerialization.spec.ts.snap b/src/generator/writers/__snapshots__/writeSerialization.spec.ts.snap index a18931f47..d0e9886df 100644 --- a/src/generator/writers/__snapshots__/writeSerialization.spec.ts.snap +++ b/src/generator/writers/__snapshots__/writeSerialization.spec.ts.snap @@ -94,10 +94,11 @@ return (cs, __tact_verify_address(raw));", }, { "code": { - "code": "slice raw = cs~load_msg_addr(); -if (raw.preload_uint(2) != 0) { + "code": "if (cs.preload_uint(2) != 0) { + slice raw = cs~load_msg_addr(); return (cs, __tact_verify_address(raw)); } else { + cs~skip_bits(2); return (cs, null()); }", "kind": "generic", @@ -4682,10 +4683,11 @@ return (cs, __tact_verify_address(raw));", }, { "code": { - "code": "slice raw = cs~load_msg_addr(); -if (raw.preload_uint(2) != 0) { + "code": "if (cs.preload_uint(2) != 0) { + slice raw = cs~load_msg_addr(); return (cs, __tact_verify_address(raw)); } else { + cs~skip_bits(2); return (cs, null()); }", "kind": "generic", @@ -9270,10 +9272,11 @@ return (cs, __tact_verify_address(raw));", }, { "code": { - "code": "slice raw = cs~load_msg_addr(); -if (raw.preload_uint(2) != 0) { + "code": "if (cs.preload_uint(2) != 0) { + slice raw = cs~load_msg_addr(); return (cs, __tact_verify_address(raw)); } else { + cs~skip_bits(2); return (cs, null()); }", "kind": "generic", diff --git a/src/generator/writers/writeStdlib.ts b/src/generator/writers/writeStdlib.ts index 7daff96a4..e57f0b405 100644 --- a/src/generator/writers/writeStdlib.ts +++ b/src/generator/writers/writeStdlib.ts @@ -61,10 +61,11 @@ export function writeStdlib(ctx: WriterContext) { ctx.context("stdlib"); ctx.body(() => { ctx.write(` - slice raw = cs~load_msg_addr(); - if (raw.preload_uint(2) != 0) { + if (cs.preload_uint(2) != 0) { + slice raw = cs~load_msg_addr(); return (cs, ${ctx.used(`__tact_verify_address`)}(raw)); } else { + cs~skip_bits(2); return (cs, null()); } `); diff --git a/src/test/__snapshots__/bugs.spec.ts.snap b/src/test/__snapshots__/bugs.spec.ts.snap index 5e645a629..52c0f29cc 100644 --- a/src/test/__snapshots__/bugs.spec.ts.snap +++ b/src/test/__snapshots__/bugs.spec.ts.snap @@ -12,12 +12,12 @@ exports[`bugs should deploy contract correctly 1`] = ` "$type": "received", "message": { "body": { - "cell": "x{178D45190000000000000000502540BE4008003C5D3B0F1C48270BF27183B56B7720CEC4D43FC522F36B959246E78EB0297F390016E3A425A4E75B646191AC9A34FE5D050BD101A5C490F87D01C66D885D09BC1082_}", + "cell": "x{178D45190000000000000000502540BE4008001C6C7938BCE1EDDD4D7179F5626FBC23A92D0521900C93D0E579C0128C1BCFDB0016E3A425A4E75B646191AC9A34FE5D050BD101A5C490F87D01C66D885D09BC1082_}", "type": "cell", }, "bounce": false, - "from": "kQAeLp2HjiQThfk4wdq1u5BnYmof4pF5tcrJI3PHWBS_nC2X", - "to": "kQAkac1EyctWyuJ-t6ptqOdCfkadI7zcO0PESJ2m2Djkk5Qt", + "from": "kQAONjycXnD27qa4vPqxN94R1JaCkMgGSehyvOAJRg3n7ROk", + "to": "kQBW5ieoSEHXuEljVf_tAb_cPCvcurQZBoW1ez4bx54-Zadw", "type": "internal", "value": "9.959886", }, @@ -38,7 +38,7 @@ exports[`bugs should deploy contract correctly 1`] = ` }, }, "bounce": false, - "from": "kQAkac1EyctWyuJ-t6ptqOdCfkadI7zcO0PESJ2m2Djkk5Qt", + "from": "kQBW5ieoSEHXuEljVf_tAb_cPCvcurQZBoW1ez4bx54-Zadw", "to": "@treasure(treasure)", "type": "internal", "value": "9.916924834", diff --git a/src/test/__snapshots__/feature-masterchain.spec.ts.snap b/src/test/__snapshots__/feature-masterchain.spec.ts.snap index 273789d18..2138d8665 100644 --- a/src/test/__snapshots__/feature-masterchain.spec.ts.snap +++ b/src/test/__snapshots__/feature-masterchain.spec.ts.snap @@ -17,7 +17,7 @@ exports[`feature-masterchain should deploy to the workchain 1`] = ` }, "bounce": true, "from": "@treasure(treasure)", - "to": "kQA20iCKIFEzO1mFx43P0wStDCq-7r64Cgzuzw2xxs3tCCeX", + "to": "kQD9Rd1f21h4jkjh1ZNxBw5DlUvPA8Yf9_X6WzPUYUUFvG07", "type": "internal", "value": "10", }, @@ -48,7 +48,7 @@ exports[`feature-masterchain should deploy to the workchain from masterchain whe }, "bounce": true, "from": "@treasure(treasure)", - "to": "kQCge9n1nOR04_y5j_vV3h4BYRPE6g49LgKZxIRNXtTHHfpO", + "to": "kQB4GR7QxoLczPfQReBFnohwnNAblXe-53Zyw_ZmpPRd99VZ", "type": "internal", "value": "10", }, @@ -79,7 +79,7 @@ exports[`feature-masterchain should deploy to the workchain when masterchain ena }, "bounce": true, "from": "@treasure(treasure)", - "to": "kQCge9n1nOR04_y5j_vV3h4BYRPE6g49LgKZxIRNXtTHHfpO", + "to": "kQB4GR7QxoLczPfQReBFnohwnNAblXe-53Zyw_ZmpPRd99VZ", "type": "internal", "value": "10", }, @@ -110,7 +110,7 @@ exports[`feature-masterchain should not deploy to the workchain from masterchain }, "bounce": true, "from": "@treasure(treasure)", - "to": "kQA20iCKIFEzO1mFx43P0wStDCq-7r64Cgzuzw2xxs3tCCeX", + "to": "kQD9Rd1f21h4jkjh1ZNxBw5DlUvPA8Yf9_X6WzPUYUUFvG07", "type": "internal", "value": "10", }, @@ -128,7 +128,7 @@ exports[`feature-masterchain should not deploy to the workchain from masterchain "type": "cell", }, "bounce": false, - "from": "kQA20iCKIFEzO1mFx43P0wStDCq-7r64Cgzuzw2xxs3tCCeX", + "from": "kQD9Rd1f21h4jkjh1ZNxBw5DlUvPA8Yf9_X6WzPUYUUFvG07", "to": "@treasure(treasure)", "type": "internal", "value": "9.989", diff --git a/src/test/feature-optionals.spec.ts b/src/test/feature-optionals.spec.ts index 036827b9b..a4e903e9a 100644 --- a/src/test/feature-optionals.spec.ts +++ b/src/test/feature-optionals.spec.ts @@ -5,6 +5,7 @@ import { SomeGenericStruct, StructWithOptionals, } from "./features/output/optionals_ContractWithOptionals"; +import { Opt4 } from "./features/output/optionals_Opt4"; import { Address, beginCell, Cell, toNano } from "@ton/core"; import { ContractSystem } from "@tact-lang/emulator"; @@ -242,4 +243,25 @@ describe("features", () => { expect(await contract.getIsNotNullF()).toBe(cs.f !== null); }); } + it("Optional address should load correctly", async () => { + const system = await ContractSystem.create(); + const treasure = system.treasure("treasure"); + const contract = system.open(await Opt4.fromInit()); + await contract.send(treasure, { value: toNano("10") }, null); + await system.run(); + + await contract.send( + treasure, + { value: toNano(1) }, + { + $$type: "OptAddr", + x: BigInt(255), + y: null, + z: BigInt(12345), + }, + ); + await system.run(); + + expect(await contract.getZ()).toEqual(12345n); + }); }); diff --git a/src/test/features/optionals-2.tact b/src/test/features/optionals-2.tact index f9030ebcf..07d6a40ee 100644 --- a/src/test/features/optionals-2.tact +++ b/src/test/features/optionals-2.tact @@ -42,4 +42,27 @@ contract Opt3 { init(arg: Struct2?) { } -} \ No newline at end of file +} + +message OptAddr { + x: Int as uint8; + y: Address?; + z: Int as uint16; +} + +contract Opt4 { + z: Int = 0; + + init() {} + + // deploy + receive() {} + + receive(msg: OptAddr) { + self.z = msg.z; + } + + get fun z(): Int { + return self.z; + } +}