From b571ec1d7cb2330abd27123cb9c0f1243abe083a Mon Sep 17 00:00:00 2001 From: Daniil Sedov Date: Thu, 31 Oct 2024 11:23:12 +0300 Subject: [PATCH] feat: `replace` and `replaceGet` map methods (#941) * refactor: rework maps testing contract completely to cover all different key-value combinations and all methods --- CHANGELOG.md | 1 + cspell.json | 1 + docs/src/content/docs/book/maps.mdx | 84 + src/abi/map.ts | 1088 +++--- .../writeSerialization.spec.ts.snap | 1607 +++++++- src/generator/writers/writeStdlib.ts | 275 +- src/imports/stdlib.ts | 276 +- src/test/e2e-emulated/contracts/maps.tact | 2934 +++++++++------ src/test/e2e-emulated/map.spec.ts | 3238 +++++++++++------ stdlib/stdlib.fc | 23 + 10 files changed, 6586 insertions(+), 2941 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 23a8e9164..fcf9784e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Destructuring of structs and messages: PR [#856](https://github.com/tact-lang/tact/pull/856) - Docs: automatic links to Web IDE from all code blocks: PR [#994](https://github.com/tact-lang/tact/pull/994) - Docs: initial semi-automated Chinese translation of the documentation: PR [#942](https://github.com/tact-lang/tact/pull/942) +- The `replace` and `replaceGet` methods for the `Map` type: PR [#941](https://github.com/tact-lang/tact/pull/941) ### Changed diff --git a/cspell.json b/cspell.json index fdbd9dac6..d43b9ea1f 100644 --- a/cspell.json +++ b/cspell.json @@ -89,6 +89,7 @@ "rangle", "rawslice", "renamer", + "replaceget", "rparen", "rugpull", "rugpulled", diff --git a/docs/src/content/docs/book/maps.mdx b/docs/src/content/docs/book/maps.mdx index 93c20a3f2..574efa07a 100644 --- a/docs/src/content/docs/book/maps.mdx +++ b/docs/src/content/docs/book/maps.mdx @@ -96,6 +96,90 @@ if (gotButUnsure != null) { } ``` +### Replace values, `.replace()` {#replace} + +

+ +To replace the value under a key, if such a key exists, use the `.replace(){:tact}` [method](/book/functions#extension-function). It returns `true{:tact}` on successful replacement and `false{:tact}` otherwise. + +```tact +// Empty map +let fizz: map = emptyMap(); + +// Setting a couple of values under different keys +fizz.set(7, 70); +fizz.set(42, 42); + +// Overriding one of the existing key-value pairs +let replaced1 = fizz.replace(7, 68); // key 7 now points to value 68 +replaced1; // true + +// Trying to replace the value in a non-existing key-value pair will do nothing +let replaced2 = fizz.replace(8, 68); // no key 8, so nothing was altered +replaced2; // false +``` + +If the given value is [`null{:tact}`](/book/optionals) and the key exists, the entry will be deleted from the map. + +```tact +// Empty map +let fizz: map = emptyMap(); + +// Setting a couple of values under different keys +fizz.set(7, 70); +fizz.set(42, 42); + +// Overriding one of the existing key-value pairs +let replaced1 = fizz.replace(7, null); // the entry under key 7 is now deleted +replaced1; // true + +// Trying to replace the value in a non-existing key-value pair will do nothing +let replaced2 = fizz.replace(8, null); // no key 8, so nothing was altered +replaced2; // false +``` + +### Replace and get old value, `.replaceGet()` {#replaceget} + +

+ +Like [`.replace()`](#replace), but instead of returning a [`Bool{:tact}`](/book/types#booleans) it returns the old (pre-replacement) value on successful replacement and [`null{:tact}`](/book/optionals) otherwise. + +```tact +// Empty map +let fizz: map = emptyMap(); + +// Setting a couple of values under different keys +fizz.set(7, 70); +fizz.set(42, 42); + +// Overriding one of the existing key-value pairs +let oldVal1 = fizz.replaceGet(7, 68); // key 7 now points to value 68 +oldVal1; // 70 + +// Trying to replace the value in a non-existing key-value pair will do nothing +let oldVal2 = fizz.replaceGet(8, 68); // no key 8, so nothing was altered +oldVal2; // null +``` + +If the given value is [`null{:tact}`](/book/optionals) and the key exists, the entry will be deleted from the map. + +```tact +// Empty map +let fizz: map = emptyMap(); + +// Setting a couple of values under different keys +fizz.set(7, 70); +fizz.set(42, 42); + +// Overriding one of the existing key-value pairs +let oldVal1 = fizz.replaceGet(7, null); // the entry under key 7 is now deleted +oldVal1; // 70 + +// Trying to replace the value in a non-existing key-value pair will do nothing +let oldVal2 = fizz.replaceGet(8, null); // no key 8, so nothing was altered +oldVal2; // null +``` + ### Delete entries, `.del()` {#del} To delete a single key-value pair (single entry), use the `.del(){:tact}` [method](/book/functions#extension-function). It returns `true{:tact}` in the case of successful deletion and `false{:tact}` otherwise. diff --git a/src/abi/map.ts b/src/abi/map.ts index 451340116..bc44095cc 100644 --- a/src/abi/map.ts +++ b/src/abi/map.ts @@ -1,201 +1,189 @@ +import { CompilerContext } from "../context"; +import { SrcInfo } from "../grammar/grammar"; +import { TypeRef } from "../types/types"; +import { WriterContext } from "../generator/Writer"; import { ops } from "../generator/writers/ops"; import { writeExpression } from "../generator/writers/writeExpression"; import { throwCompilationError } from "../errors"; import { getType } from "../types/resolveDescriptors"; import { AbiFunction } from "./AbiFunction"; - +import { AstExpression } from "../grammar/ast"; + +// Helper functions to avoid redundancy +function checkArgumentsLength( + args: (TypeRef | undefined)[], + expected: number, + message: string, + ref: SrcInfo, +): void { + if (args.length !== expected || args.some((arg) => arg === undefined)) { + throwCompilationError(message, ref); + } +} + +function checkMapType( + self: TypeRef | undefined, + ref: SrcInfo, +): asserts self is { + kind: "map"; + key: string; + keyAs: string | null; + value: string; + valueAs: string | null; +} { + if (!self || self.kind !== "map") { + throwCompilationError("expects a map as self argument", ref); + } + if (self.key !== "Int" && self.key !== "Address") { + throwCompilationError("expects a map with Int or Address keys", ref); + } +} + +function checkKeyType( + key: TypeRef | undefined, + expectedType: string, + ref: SrcInfo, +): void { + if ( + !key || + key.kind !== "ref" || + key.optional || + key.name !== expectedType + ) { + throwCompilationError( + `expects a "${expectedType}" as first argument`, + ref, + ); + } +} + +function checkValueType( + value: TypeRef | undefined, + expectedType: string, + ref: SrcInfo, +): void { + if (!value || (value.kind !== "null" && value.kind !== "ref")) { + throwCompilationError("expects a direct type as second argument", ref); + } + if (value.kind !== "null" && value.name !== expectedType) { + throwCompilationError( + `expects a "${expectedType}" as second argument`, + ref, + ); + } +} + +function resolveMapKeyBits( + self: { key: string; keyAs: string | null }, + ref: SrcInfo, +): { bits: number; kind: string } { + if (self.key === "Int") { + if (self.keyAs?.startsWith("int")) { + return { bits: parseInt(self.keyAs.slice(3), 10), kind: "int" }; + } + if (self.keyAs?.startsWith("uint")) { + return { bits: parseInt(self.keyAs.slice(4), 10), kind: "uint" }; + } + return { bits: 257, kind: "int" }; // Default for "Int" keys + } else if (self.key === "Address") { + return { bits: 267, kind: "slice" }; + } + throwCompilationError(`Unsupported key type: ${self.key}`, ref); +} + +function handleStructOrOtherValue( + self: { value: string; valueAs: string | null }, + value: TypeRef, + resolved: string[], + ctx: WriterContext, + ref: SrcInfo, + bits: number, + kind: string, + operation: string = "set", +): string { + const t = getType(ctx.ctx, self.value); + if (["contract", "trait"].includes(t.kind)) { + throwCompilationError(`"${t.name}" can't be value of a map`, ref); + } + if (t.kind === "struct") { + const funcName = `__tact_dict_${operation}_${kind}_cell`; + ctx.used(funcName); + const writerFunc = + value.kind === "ref" && !value.optional + ? ops.writerCell(t.name, ctx) + : ops.writerCellOpt(t.name, ctx); + return `${resolved[0]}~${funcName}(${bits}, ${resolved[1]}, ${writerFunc}(${resolved[2]}))`; + } + throwCompilationError(`"${t.name}" can't be value of a map`, ref); +} + +// The fully refactored MapFunctions object export const MapFunctions: Map = new Map([ [ "set", { name: "set", - resolve(ctx, args, ref) { - // Check arguments - if (args.length !== 3) { - throwCompilationError("set expects two arguments", ref); // Should not happen - } - const self = args[0]!; - const key = args[1]!; - const value = args[2]!; - if (self.kind !== "map") { - throwCompilationError( - "set expects a map as self argument", - ref, - ); // Should not happen - } - - // Resolve map types - if (self.key !== "Int" && self.key !== "Address") { - throwCompilationError( - "set expects a map with Int or Address keys", - ref, - ); - } - - // Check key type - if (key.kind !== "ref" || key.optional) { - throwCompilationError( - "set expects a direct type as first argument", - ref, - ); - } - if (key.name !== self.key) { - throwCompilationError( - `set expects a "${self.key}" as first argument`, - ref, - ); - } - - // Check value type - if (value.kind !== "null" && value.kind !== "ref") { - throwCompilationError( - "set expects a direct type as second argument", - ref, - ); - } - if (value.kind !== "null" && value.name !== self.value) { - throwCompilationError( - `set expects a "${self.value}" as second argument`, - ref, - ); - } + resolve( + ctx: CompilerContext, + args: (TypeRef | undefined)[], + ref: SrcInfo, + ) { + checkArgumentsLength(args, 3, "set expects two arguments", ref); + + const [self, key, value] = args; + checkMapType(self, ref); + checkKeyType(key, self.key, ref); + checkValueType(value, self.value, ref); // Returns nothing return { kind: "void" }; }, - generate: (ctx, args, exprs, ref) => { - // Check arguments - if (args.length !== 3) { - throwCompilationError("set expects two arguments", ref); // Ignore self argument - } - const self = args[0]!; - const value = args[2]!; - if (self.kind !== "map") { - throwCompilationError( - "set expects a map as self argument", - ref, - ); // Should not happen - } + generate( + ctx: WriterContext, + args: (TypeRef | undefined)[], + exprs: AstExpression[], + ref: SrcInfo, + ) { + checkArgumentsLength(args, 3, "set expects two arguments", ref); - // Render expressions - const resolved = exprs.map((v) => writeExpression(v, ctx)); + const [self, , value] = args; + checkMapType(self, ref); - // Handle Int key - if (self.key === "Int") { - let bits = 257; - let kind = "int"; - if (self.keyAs?.startsWith("int")) { - bits = parseInt(self.keyAs.slice(3), 10); - } else if (self.keyAs?.startsWith("uint")) { - bits = parseInt(self.keyAs.slice(4), 10); - kind = "uint"; - } - if (self.value === "Int") { - let vBits = 257; - let vKind = "int"; - if (self.valueAs?.startsWith("int")) { - vBits = parseInt(self.valueAs.slice(3), 10); - } else if (self.valueAs?.startsWith("uint")) { - vBits = parseInt(self.valueAs.slice(4), 10); - vKind = "uint"; - } - ctx.used(`__tact_dict_set_${kind}_${vKind}`); - return `${resolved[0]}~__tact_dict_set_${kind}_${vKind}(${bits}, ${resolved[1]}, ${resolved[2]}, ${vBits})`; - } else if (self.value === "Bool") { - ctx.used(`__tact_dict_set_${kind}_int`); - return `${resolved[0]}~__tact_dict_set_${kind}_int(${bits}, ${resolved[1]}, ${resolved[2]}, 1)`; - } else if (self.value === "Cell") { - ctx.used(`__tact_dict_set_${kind}_cell`); - return `${resolved[0]}~__tact_dict_set_${kind}_cell(${bits}, ${resolved[1]}, ${resolved[2]})`; - } else if (self.value === "Address") { - ctx.used(`__tact_dict_set_${kind}_slice`); - return `${resolved[0]}~__tact_dict_set_${kind}_slice(${bits}, ${resolved[1]}, ${resolved[2]})`; - } else { - const t = getType(ctx.ctx, self.value); - if (t.kind === "contract") { - throwCompilationError( - `Contract can't be value of a map`, - ref, - ); - } - if (t.kind === "trait") { - throwCompilationError( - `Trait can't be value of a map`, - ref, - ); - } - if (t.kind === "struct") { - ctx.used(`__tact_dict_set_${kind}_cell`); - if (value.kind === "ref" && !value.optional) { - return `${resolved[0]}~__tact_dict_set_${kind}_cell(${bits}, ${resolved[1]}, ${ops.writerCell(t.name, ctx)}(${resolved[2]}))`; - } else { - return `${resolved[0]}~__tact_dict_set_${kind}_cell(${bits}, ${resolved[1]}, ${ops.writerCellOpt(t.name, ctx)}(${resolved[2]}))`; - } - } else { - throwCompilationError( - `"${t.name}" can't be value of a map`, - ref, - ); - } - } - } - - // Handle address key - if (self.key === "Address") { - if (self.value === "Int") { - let vBits = 257; - let vKind = "int"; - if (self.valueAs?.startsWith("int")) { - vBits = parseInt(self.valueAs.slice(3), 10); - } else if (self.valueAs?.startsWith("uint")) { - vBits = parseInt(self.valueAs.slice(4), 10); - vKind = "uint"; - } - ctx.used(`__tact_dict_set_slice_${vKind}`); - return `${resolved[0]}~__tact_dict_set_slice_${vKind}(267, ${resolved[1]}, ${resolved[2]}, ${vBits})`; - } else if (self.value === "Bool") { - ctx.used(`__tact_dict_set_slice_int`); - return `${resolved[0]}~__tact_dict_set_slice_int(267, ${resolved[1]}, ${resolved[2]}, 1)`; - } else if (self.value === "Cell") { - ctx.used(`__tact_dict_set_slice_cell`); - return `${resolved[0]}~__tact_dict_set_slice_cell(267, ${resolved[1]}, ${resolved[2]})`; - } else if (self.value === "Address") { - ctx.used(`__tact_dict_set_slice_slice`); - return `${resolved[0]}~__tact_dict_set_slice_slice(267, ${resolved[1]}, ${resolved[2]})`; - } else { - const t = getType(ctx.ctx, self.value); - if (t.kind === "contract") { - throwCompilationError( - `Contract can't be value of a map`, - ref, - ); - } - if (t.kind === "trait") { - throwCompilationError( - `Trait can't be value of a map`, - ref, - ); - } - if (t.kind === "struct") { - ctx.used(`__tact_dict_set_slice_cell`); - if (value.kind === "ref" && !value.optional) { - return `${resolved[0]}~__tact_dict_set_slice_cell(267, ${resolved[1]}, ${ops.writerCell(t.name, ctx)}(${resolved[2]}))`; - } else { - return `${resolved[0]}~__tact_dict_set_slice_cell(267, ${resolved[1]}, ${ops.writerCellOpt(t.name, ctx)}(${resolved[2]}))`; - } - } else { - throwCompilationError( - `"${t.name}" can't be value of a map`, - ref, - ); - } + const resolved = exprs.map((v) => writeExpression(v, ctx)); + const { bits, kind } = resolveMapKeyBits(self, ref); + + if (self.value === "Int") { + let vBits = 257; + let vKind = "int"; + if (self.valueAs?.startsWith("int")) { + vBits = parseInt(self.valueAs.slice(3), 10); + } else if (self.valueAs?.startsWith("uint")) { + vBits = parseInt(self.valueAs.slice(4), 10); + vKind = "uint"; } + ctx.used(`__tact_dict_set_${kind}_${vKind}`); + return `${resolved[0]}~__tact_dict_set_${kind}_${vKind}(${bits}, ${resolved[1]}, ${resolved[2]}, ${vBits})`; + } else if (self.value === "Bool") { + ctx.used(`__tact_dict_set_${kind}_int`); + return `${resolved[0]}~__tact_dict_set_${kind}_int(${bits}, ${resolved[1]}, ${resolved[2]}, 1)`; + } else if (self.value === "Cell") { + ctx.used(`__tact_dict_set_${kind}_cell`); + return `${resolved[0]}~__tact_dict_set_${kind}_cell(${bits}, ${resolved[1]}, ${resolved[2]})`; + } else if (self.value === "Address") { + ctx.used(`__tact_dict_set_${kind}_slice`); + return `${resolved[0]}~__tact_dict_set_${kind}_slice(${bits}, ${resolved[1]}, ${resolved[2]})`; + } else { + return handleStructOrOtherValue( + self, + value!, + resolved, + ctx, + ref, + bits, + kind, + "set", + ); } - - throwCompilationError( - `set expects a map with Int or Address keys`, - ref, - ); }, }, ], @@ -203,156 +191,76 @@ export const MapFunctions: Map = new Map([ "get", { name: "get", - resolve(ctx, args, ref) { - // Check arguments - if (args.length !== 2) { - throwCompilationError("set expects one argument", ref); // Ignore self argument - } - const self = args[0]!; - const key = args[1]!; - if (self.kind !== "map") { - throwCompilationError( - "set expects a map as self argument", - ref, - ); // Should not happen - } + resolve( + ctx: CompilerContext, + args: (TypeRef | undefined)[], + ref: SrcInfo, + ) { + checkArgumentsLength(args, 2, "get expects one argument", ref); - // Check key type - if (key.kind !== "ref" || key.optional) { - throwCompilationError( - "set expects a direct type as first argument", - ref, - ); - } - if (key.name !== self.key) { - throwCompilationError( - `set expects a "${self.key}" as first argument`, - ref, - ); - } + const [self, key] = args; + checkMapType(self, ref); + checkKeyType(key, self.key, ref); return { kind: "ref", name: self.value, optional: true }; }, - generate: (ctx, args, exprs, ref) => { - if (args.length !== 2) { - throwCompilationError("set expects one argument", ref); // Ignore self argument - } - const self = args[0]!; - if (self.kind !== "map") { - throwCompilationError( - "set expects a map as self argument", - ref, - ); // Should not happen - } + generate( + ctx: WriterContext, + args: (TypeRef | undefined)[], + exprs: AstExpression[], + ref: SrcInfo, + ) { + checkArgumentsLength(args, 2, "get expects one argument", ref); - // Render expressions - const resolved = exprs.map((v) => writeExpression(v, ctx)); + const [self] = args; + checkMapType(self, ref); - // Handle Int key - if (self.key === "Int") { - let bits = 257; - let kind = "int"; - if (self.keyAs?.startsWith("int")) { - bits = parseInt(self.keyAs.slice(3), 10); - } else if (self.keyAs?.startsWith("uint")) { - bits = parseInt(self.keyAs.slice(4), 10); - kind = "uint"; + const resolved = exprs.map((v) => writeExpression(v, ctx)); + const { bits, kind } = resolveMapKeyBits(self, ref); + + if (self.value === "Int") { + let vBits = 257; + let vKind = "int"; + if (self.valueAs?.startsWith("int")) { + vBits = parseInt(self.valueAs.slice(3), 10); + } else if (self.valueAs?.startsWith("uint")) { + vBits = parseInt(self.valueAs.slice(4), 10); + vKind = "uint"; } - if (self.value === "Int") { - let vBits = 257; - let vKind = "int"; - if (self.valueAs?.startsWith("int")) { - vBits = parseInt(self.valueAs.slice(3), 10); - } else if (self.valueAs?.startsWith("uint")) { - vBits = parseInt(self.valueAs.slice(4), 10); - vKind = "uint"; - } - ctx.used(`__tact_dict_get_${kind}_${vKind}`); - return `__tact_dict_get_${kind}_${vKind}(${resolved[0]}, ${bits}, ${resolved[1]}, ${vBits})`; - } else if (self.value === "Bool") { - ctx.used(`__tact_dict_get_${kind}_int`); - return `__tact_dict_get_${kind}_int(${resolved[0]}, ${bits}, ${resolved[1]}, 1)`; - } else if (self.value === "Cell") { - ctx.used(`__tact_dict_get_${kind}_cell`); - return `__tact_dict_get_${kind}_cell(${resolved[0]}, ${bits}, ${resolved[1]})`; - } else if (self.value === "Address") { - ctx.used(`__tact_dict_get_${kind}_slice`); - return `__tact_dict_get_${kind}_slice(${resolved[0]}, ${bits}, ${resolved[1]})`; - } else { - const t = getType(ctx.ctx, self.value); - if (t.kind === "contract") { - throwCompilationError( - `Contract can't be value of a map`, - ref, - ); - } - if (t.kind === "trait") { - throwCompilationError( - `Trait can't be value of a map`, - ref, - ); - } - if (t.kind === "struct") { - ctx.used(`__tact_dict_get_${kind}_cell`); - return `${ops.readerOpt(t.name, ctx)}(__tact_dict_get_${kind}_cell(${resolved[0]}, ${bits}, ${resolved[1]}))`; - } else { - throwCompilationError( - `"${t.name}" can't be value of a map`, - ref, - ); - } + ctx.used(`__tact_dict_get_${kind}_${vKind}`); + return `__tact_dict_get_${kind}_${vKind}(${resolved[0]}, ${bits}, ${resolved[1]}, ${vBits})`; + } else if (self.value === "Bool") { + ctx.used(`__tact_dict_get_${kind}_int`); + return `__tact_dict_get_${kind}_int(${resolved[0]}, ${bits}, ${resolved[1]}, 1)`; + } else if (self.value === "Cell") { + ctx.used(`__tact_dict_get_${kind}_cell`); + return `__tact_dict_get_${kind}_cell(${resolved[0]}, ${bits}, ${resolved[1]})`; + } else if (self.value === "Address") { + ctx.used(`__tact_dict_get_${kind}_slice`); + return `__tact_dict_get_${kind}_slice(${resolved[0]}, ${bits}, ${resolved[1]})`; + } else { + const t = getType(ctx.ctx, self.value); + if (t.kind === "contract") { + throwCompilationError( + `Contract can't be value of a map`, + ref, + ); } - } - - // Handle Address key - if (self.key === "Address") { - if (self.value === "Int") { - let vBits = 257; - let vKind = "int"; - if (self.valueAs?.startsWith("int")) { - vBits = parseInt(self.valueAs.slice(3), 10); - } else if (self.valueAs?.startsWith("uint")) { - vBits = parseInt(self.valueAs.slice(4), 10); - vKind = "uint"; - } - ctx.used(`__tact_dict_get_slice_${vKind}`); - return `__tact_dict_get_slice_${vKind}(${resolved[0]}, 267, ${resolved[1]}, ${vBits})`; - } else if (self.value === "Bool") { - ctx.used(`__tact_dict_get_slice_int`); - return `__tact_dict_get_slice_int(${resolved[0]}, 267, ${resolved[1]}, 1)`; - } else if (self.value === "Cell") { - ctx.used(`__tact_dict_get_slice_cell`); - return `__tact_dict_get_slice_cell(${resolved[0]}, 267, ${resolved[1]})`; - } else if (self.value === "Address") { - ctx.used(`__tact_dict_get_slice_slice`); - return `__tact_dict_get_slice_slice(${resolved[0]}, 267, ${resolved[1]})`; - } else { - const t = getType(ctx.ctx, self.value); - if (t.kind === "contract") { - throwCompilationError( - `Contract can't be value of a map`, - ref, - ); - } - if (t.kind === "trait") { - throwCompilationError( - `Trait can't be value of a map`, - ref, - ); - } - if (t.kind === "struct") { - ctx.used(`__tact_dict_get_slice_cell`); - return `${ops.readerOpt(t.name, ctx)}(__tact_dict_get_slice_cell(${resolved[0]}, 267, ${resolved[1]}))`; - } else { - throwCompilationError( - `"${t.name}" can't be value of a map`, - ref, - ); - } + if (t.kind === "trait") { + throwCompilationError( + `Trait can't be value of a map`, + ref, + ); + } + if (t.kind === "struct") { + ctx.used(`__tact_dict_get_${kind}_cell`); + return `${ops.readerOpt(t.name, ctx)}(__tact_dict_get_${kind}_cell(${resolved[0]}, ${bits}, ${resolved[1]}))`; } + throwCompilationError( + `"${t.name}" can't be value of a map`, + ref, + ); } - - throwCompilationError(`set expects a map with Int keys`, ref); }, }, ], @@ -360,73 +268,46 @@ export const MapFunctions: Map = new Map([ "del", { name: "del", - resolve(ctx, args, ref) { - // Check arguments - if (args.length !== 2) { - throwCompilationError("del expects one argument", ref); // Ignore self argument - } - const self = args[0]!; - const key = args[1]!; - if (self.kind !== "map") { - throwCompilationError( - "del expects a map as self argument", - ref, - ); // Should not happen - } + resolve( + ctx: CompilerContext, + args: (TypeRef | undefined)[], + ref: SrcInfo, + ) { + checkArgumentsLength(args, 2, "del expects one argument", ref); - // Check key type - if (key.kind !== "ref" || key.optional) { - throwCompilationError( - "del expects a direct type as first argument", - ref, - ); - } - if (key.name !== self.key) { - throwCompilationError( - `del expects a "${self.key}" as first argument`, - ref, - ); - } + const [self, key] = args; + checkMapType(self, ref); + checkKeyType(key, self.key, ref); // Returns boolean return { kind: "ref", name: "Bool", optional: false }; }, - generate: (ctx, args, exprs, ref) => { - if (args.length !== 2) { - throwCompilationError("del expects one argument", ref); // Ignore self argument - } - const self = args[0]!; - if (self.kind !== "map") { - throwCompilationError( - "del expects a map as self argument", - ref, - ); // Should not happen - } + generate( + ctx: WriterContext, + args: (TypeRef | undefined)[], + exprs: AstExpression[], + ref: SrcInfo, + ) { + checkArgumentsLength(args, 2, "del expects one argument", ref); + + const [self] = args; + checkMapType(self, ref); - // Render expressions const resolved = exprs.map((v) => writeExpression(v, ctx)); + const { bits, kind } = resolveMapKeyBits(self, ref); - // Handle Int key if (self.key === "Int") { - let bits = 257; - let kind = "int"; - if (self.keyAs?.startsWith("int")) { - bits = parseInt(self.keyAs.slice(3), 10); - } else if (self.keyAs?.startsWith("uint")) { - bits = parseInt(self.keyAs.slice(4), 10); - kind = "uint"; - } ctx.used(`__tact_dict_delete_${kind}`); return `${resolved[0]}~__tact_dict_delete_${kind}(${bits}, ${resolved[1]})`; - } - - // Handle Address key - if (self.key === "Address") { + } else if (self.key === "Address") { ctx.used(`__tact_dict_delete`); return `${resolved[0]}~__tact_dict_delete(267, ${resolved[1]})`; } - throwCompilationError(`del expects a map with Int keys`, ref); + throwCompilationError( + `del expects a map with Int or Address keys`, + ref, + ); }, }, ], @@ -434,32 +315,38 @@ export const MapFunctions: Map = new Map([ "asCell", { name: "asCell", - resolve(ctx, args, ref) { - // Check arguments - if (args.length !== 1) { - throwCompilationError("asCell expects one argument", ref); // Ignore self argument - } - const self = args[0]!; - if (self.kind !== "map") { - throwCompilationError( - "asCell expects a map as self argument", - ref, - ); // Should not happen - } + resolve( + ctx: CompilerContext, + args: (TypeRef | undefined)[], + ref: SrcInfo, + ) { + checkArgumentsLength( + args, + 1, + "asCell expects one argument", + ref, + ); + + const [self] = args; + checkMapType(self, ref); return { kind: "ref", name: "Cell", optional: true }; }, - generate: (ctx, args, exprs, ref) => { - if (args.length !== 1) { - throwCompilationError("asCell expects one argument", ref); // Ignore self argument - } - const self = args[0]!; - if (self.kind !== "map") { - throwCompilationError( - "asCell expects a map as self argument", - ref, - ); // Should not happen - } + generate( + ctx: WriterContext, + args: (TypeRef | undefined)[], + exprs: AstExpression[], + ref: SrcInfo, + ) { + checkArgumentsLength( + args, + 1, + "asCell expects one argument", + ref, + ); + + const [self] = args; + checkMapType(self, ref); return writeExpression(exprs[0]!, ctx); }, @@ -469,32 +356,38 @@ export const MapFunctions: Map = new Map([ "isEmpty", { name: "isEmpty", - resolve(ctx, args, ref) { - // Check arguments - if (args.length !== 1) { - throwCompilationError("isEmpty expects one argument", ref); // Ignore self argument - } - const self = args[0]!; - if (self.kind !== "map") { - throwCompilationError( - "isEmpty expects a map as self argument", - ref, - ); // Should not happen - } + resolve( + ctx: CompilerContext, + args: (TypeRef | undefined)[], + ref: SrcInfo, + ) { + checkArgumentsLength( + args, + 1, + "isEmpty expects one argument", + ref, + ); + + const [self] = args; + checkMapType(self, ref); return { kind: "ref", name: "Bool", optional: false }; }, - generate: (ctx, args, exprs, ref) => { - if (args.length !== 1) { - throwCompilationError("isEmpty expects one argument", ref); // Ignore self argument - } - const self = args[0]!; - if (self.kind !== "map") { - throwCompilationError( - "isEmpty expects a map as self argument", - ref, - ); // Should not happen - } + generate( + ctx: WriterContext, + args: (TypeRef | undefined)[], + exprs: AstExpression[], + ref: SrcInfo, + ) { + checkArgumentsLength( + args, + 1, + "isEmpty expects one argument", + ref, + ); + + const [self] = args; + checkMapType(self, ref); return `null?(${writeExpression(exprs[0]!, ctx)})`; }, @@ -504,74 +397,54 @@ export const MapFunctions: Map = new Map([ "exists", { name: "exists", - resolve(ctx, args, ref) { - // Check arguments - if (args.length !== 2) { - throwCompilationError("exists expects one argument", ref); // Ignore self argument - } - const self = args[0]!; - const key = args[1]!; - if (self.kind !== "map") { - throwCompilationError( - "exists expects a map as self argument", - ref, - ); // Should not happen - } + resolve( + ctx: CompilerContext, + args: (TypeRef | undefined)[], + ref: SrcInfo, + ) { + checkArgumentsLength( + args, + 2, + "exists expects one argument", + ref, + ); - // Check key type - if (key.kind !== "ref" || key.optional) { - throwCompilationError( - "exists expects a direct type as first argument", - ref, - ); - } - if (key.name !== self.key) { - throwCompilationError( - `exists expects a "${self.key}" as first argument`, - ref, - ); - } + const [self, key] = args; + checkMapType(self, ref); + checkKeyType(key, self.key, ref); // Returns boolean return { kind: "ref", name: "Bool", optional: false }; }, - generate: (ctx, args, exprs, ref) => { - if (args.length !== 2) { - throwCompilationError("exists expects one argument", ref); // Ignore self argument - } - const self = args[0]!; - if (self.kind !== "map") { - throwCompilationError( - "exists expects a map as self argument", - ref, - ); // Should not happen - } + generate( + ctx: WriterContext, + args: (TypeRef | undefined)[], + exprs: AstExpression[], + ref: SrcInfo, + ) { + checkArgumentsLength( + args, + 2, + "exists expects one argument", + ref, + ); + + const [self] = args; + checkMapType(self, ref); - // Render expressions const resolved = exprs.map((v) => writeExpression(v, ctx)); + const { bits, kind } = resolveMapKeyBits(self, ref); - // Handle Int key if (self.key === "Int") { - let bits = 257; - let kind = "int"; - if (self.keyAs?.startsWith("int")) { - bits = parseInt(self.keyAs.slice(3), 10); - } else if (self.keyAs?.startsWith("uint")) { - bits = parseInt(self.keyAs.slice(4), 10); - kind = "uint"; - } ctx.used(`__tact_dict_exists_${kind}`); return `__tact_dict_exists_${kind}(${resolved[0]}, ${bits}, ${resolved[1]})`; - } - - // Handle Address key - if (self.key === "Address") { + } else if (self.key === "Address") { ctx.used(`__tact_dict_exists_slice`); return `__tact_dict_exists_slice(${resolved[0]}, 267, ${resolved[1]})`; } throwCompilationError( - `exists expects a map with Int keys`, + `exists expects a map with Int or Address keys`, ref, ); }, @@ -581,69 +454,240 @@ export const MapFunctions: Map = new Map([ "deepEquals", { name: "deepEquals", - resolve(ctx, args, ref) { - // Check arguments - if (args.length !== 2) { - throwCompilationError( - "deepEquals expects two arguments", - ref, - ); // Ignore self argument - } - const self = args[0]!; - const other = args[1]!; - if (self.kind !== "map") { - throwCompilationError( - "deepEquals expects a map as self argument", - ref, - ); // Should not happen - } - if (other.kind !== "map") { - throwCompilationError( - "deepEquals expects a map as other argument", - ref, - ); // Should not happen - } + resolve( + ctx: CompilerContext, + args: (TypeRef | undefined)[], + ref: SrcInfo, + ) { + checkArgumentsLength( + args, + 2, + "deepEquals expects two arguments", + ref, + ); + + const [self, other] = args; + checkMapType(self, ref); + checkMapType(other, ref); return { kind: "ref", name: "Bool", optional: false }; }, - generate: (ctx, args, exprs, ref) => { - if (args.length !== 2) { + generate( + ctx: WriterContext, + args: (TypeRef | undefined)[], + exprs: AstExpression[], + ref: SrcInfo, + ) { + checkArgumentsLength( + args, + 2, + "deepEquals expects two arguments", + ref, + ); + + const [self, other] = args; + checkMapType(self, ref); + checkMapType(other, ref); + + // Determine key length based on key type + let keyLength: number; + if (self.key === "Int") { + if (self.keyAs) { + if (self.keyAs.startsWith("int")) { + keyLength = parseInt(self.keyAs.slice(3), 10); + } else if (self.keyAs.startsWith("uint")) { + keyLength = parseInt(self.keyAs.slice(4), 10); + } else { + throwCompilationError( + "Invalid key serialization type", + ref, + ); + } + } else { + keyLength = 257; + } + } else if (self.key === "Address") { + keyLength = 267; + } else { throwCompilationError( - "deepEquals expects two arguments", + `Unsupported key type: ${self.key}`, ref, - ); // Ignore self argument + ); } - const self = args[0]!; - const other = args[1]!; - if (self.kind !== "map") { - throwCompilationError( - "deepEquals expects a map as self argument", + + ctx.used("__tact_dict_eq"); + return `__tact_dict_eq(${writeExpression(exprs[0]!, ctx)}, ${writeExpression(exprs[1]!, ctx)}, ${keyLength})`; + }, + }, + ], + [ + "replace", + { + name: "replace", + resolve( + ctx: CompilerContext, + args: (TypeRef | undefined)[], + ref: SrcInfo, + ) { + checkArgumentsLength( + args, + 3, + "replace expects two arguments", + ref, + ); + + const [self, key, value] = args; + checkMapType(self, ref); + checkKeyType(key, self.key, ref); + checkValueType(value, self.value, ref); + + // Returns boolean indicating if the key was replaced + return { kind: "ref", name: "Bool", optional: false }; + }, + generate( + ctx: WriterContext, + args: (TypeRef | undefined)[], + exprs: AstExpression[], + ref: SrcInfo, + ) { + checkArgumentsLength( + args, + 3, + "replace expects two arguments", + ref, + ); + + const [self, , value] = args; + checkMapType(self, ref); + + const resolved = exprs.map((v) => writeExpression(v, ctx)); + const { bits, kind } = resolveMapKeyBits(self, ref); + + if (self.value === "Int") { + let vBits = 257; + let vKind = "int"; + if (self.valueAs?.startsWith("int")) { + vBits = parseInt(self.valueAs.slice(3), 10); + } else if (self.valueAs?.startsWith("uint")) { + vBits = parseInt(self.valueAs.slice(4), 10); + vKind = "uint"; + } + ctx.used(`__tact_dict_replace_${kind}_${vKind}`); + return `${resolved[0]}~__tact_dict_replace_${kind}_${vKind}(${bits}, ${resolved[1]}, ${resolved[2]}, ${vBits})`; + } else if (self.value === "Bool") { + ctx.used(`__tact_dict_replace_${kind}_int`); + return `${resolved[0]}~__tact_dict_replace_${kind}_int(${bits}, ${resolved[1]}, ${resolved[2]}, 1)`; + } else if (self.value === "Cell") { + ctx.used(`__tact_dict_replace_${kind}_cell`); + return `${resolved[0]}~__tact_dict_replace_${kind}_cell(${bits}, ${resolved[1]}, ${resolved[2]})`; + } else if (self.value === "Address") { + ctx.used(`__tact_dict_replace_${kind}_slice`); + return `${resolved[0]}~__tact_dict_replace_${kind}_slice(${bits}, ${resolved[1]}, ${resolved[2]})`; + } else { + return handleStructOrOtherValue( + self, + value!, + resolved, + ctx, ref, - ); // Should not happen + bits, + kind, + "replace", + ); } - if (other.kind !== "map") { + }, + }, + ], + [ + "replaceGet", + { + name: "replaceGet", + resolve( + ctx: CompilerContext, + args: (TypeRef | undefined)[], + ref: SrcInfo, + ) { + checkArgumentsLength( + args, + 3, + "replaceGet expects two arguments", + ref, + ); + + const [self, key, value] = args; + checkMapType(self, ref); + checkKeyType(key, self.key, ref); + checkValueType(value, self.value, ref); + + // Returns the previous value if it exists + return { kind: "ref", name: self.value, optional: true }; + }, + generate( + ctx: WriterContext, + args: (TypeRef | undefined)[], + exprs: AstExpression[], + ref: SrcInfo, + ) { + checkArgumentsLength( + args, + 3, + "replaceGet expects two arguments", + ref, + ); + + const [self, , value] = args; + checkMapType(self, ref); + + const resolved = exprs.map((v) => writeExpression(v, ctx)); + const { bits, kind } = resolveMapKeyBits(self, ref); + + if (self.value === "Int") { + let vBits = 257; + let vKind = "int"; + if (self.valueAs?.startsWith("int")) { + vBits = parseInt(self.valueAs.slice(3), 10); + } else if (self.valueAs?.startsWith("uint")) { + vBits = parseInt(self.valueAs.slice(4), 10); + vKind = "uint"; + } + ctx.used(`__tact_dict_replaceget_${kind}_${vKind}`); + return `${resolved[0]}~__tact_dict_replaceget_${kind}_${vKind}(${bits}, ${resolved[1]}, ${resolved[2]}, ${vBits})`; + } else if (self.value === "Bool") { + ctx.used(`__tact_dict_replaceget_${kind}_int`); + return `${resolved[0]}~__tact_dict_replaceget_${kind}_int(${bits}, ${resolved[1]}, ${resolved[2]}, 1)`; + } else if (self.value === "Cell") { + ctx.used(`__tact_dict_replaceget_${kind}_cell`); + return `${resolved[0]}~__tact_dict_replaceget_${kind}_cell(${bits}, ${resolved[1]}, ${resolved[2]})`; + } else if (self.value === "Address") { + ctx.used(`__tact_dict_replaceget_${kind}_slice`); + return `${resolved[0]}~__tact_dict_replaceget_${kind}_slice(${bits}, ${resolved[1]}, ${resolved[2]})`; + } else { + const t = getType(ctx.ctx, self.value); + if (t.kind === "contract") { + throwCompilationError( + `Contract can't be value of a map`, + ref, + ); + } + if (t.kind === "trait") { + throwCompilationError( + `Trait can't be value of a map`, + ref, + ); + } + if (t.kind === "struct") { + const writerFunc = + value!.kind === "ref" && !value!.optional + ? ops.writerCell(t.name, ctx) + : ops.writerCellOpt(t.name, ctx); + ctx.used(`__tact_dict_replaceget_${kind}_cell`); + return `${ops.readerOpt(t.name, ctx)}(${resolved[0]}~__tact_dict_replaceget_${kind}_cell(${bits}, ${resolved[1]}, ${writerFunc}(${resolved[2]})))`; + } throwCompilationError( - "deepEquals expects a map as other argument", + `"${t.name}" can't be value of a map`, ref, - ); // Should not happen + ); } - - // 257 for int, 267 for address - const keyLength = - self.key === "Int" - ? self.keyAs - ? self.keyAs.startsWith("int") - ? parseInt(self.keyAs.slice(3)) - : self.keyAs.startsWith("uint") - ? parseInt(self.keyAs.slice(4)) - : throwCompilationError( - "Invalid key serialization type", // Should not happen - ref, - ) - : 257 - : 267; - - return `${ctx.used("__tact_dict_eq")}(${writeExpression(exprs[0]!, ctx)}, ${writeExpression(exprs[1]!, ctx)}, ${keyLength})`; }, }, ], diff --git a/src/generator/writers/__snapshots__/writeSerialization.spec.ts.snap b/src/generator/writers/__snapshots__/writeSerialization.spec.ts.snap index 40dd6eb73..fbf26704e 100644 --- a/src/generator/writers/__snapshots__/writeSerialization.spec.ts.snap +++ b/src/generator/writers/__snapshots__/writeSerialization.spec.ts.snap @@ -264,6 +264,32 @@ return __tact_create_address(chain, hash);", "name": "__tact_dict_set_ref", "signature": "((cell), ()) __tact_dict_set_ref(cell dict, int key_len, slice index, cell value)", }, + { + "code": { + "code": "DICTREPLACEREF", + "kind": "asm", + "shuffle": "(value index dict key_len)", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set {}, + "name": "__tact_dict_replace_ref", + "signature": "((cell), (int)) __tact_dict_replace_ref(cell dict, int key_len, slice index, cell value)", + }, + { + "code": { + "code": "DICTREPLACEGETREF NULLSWAPIFNOT", + "kind": "asm", + "shuffle": "(value index dict key_len)", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set {}, + "name": "__tact_dict_replaceget_ref", + "signature": "((cell), (cell, int)) __tact_dict_replaceget_ref(cell dict, int key_len, slice index, cell value)", + }, { "code": { "code": "DICTGET NULLSWAPIFNOT", @@ -279,7 +305,7 @@ return __tact_create_address(chain, hash);", }, { "code": { - "code": "DICTDELGET NULLSWAPIFNOT2", + "code": "DICTDELGET NULLSWAPIFNOT", "kind": "asm", "shuffle": "(index dict key_len)", }, @@ -290,6 +316,19 @@ return __tact_create_address(chain, hash);", "name": "__tact_dict_delete_get", "signature": "(cell, (slice, int)) __tact_dict_delete_get(cell dict, int key_len, slice index)", }, + { + "code": { + "code": "DICTDELGETREF NULLSWAPIFNOT", + "kind": "asm", + "shuffle": "(index dict key_len)", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set {}, + "name": "__tact_dict_delete_get_ref", + "signature": "(cell, (cell, int)) __tact_dict_delete_get_ref(cell dict, int key_len, slice index)", + }, { "code": { "code": "DICTGETREF NULLSWAPIFNOT", @@ -1781,6 +1820,48 @@ if (flag) { "name": "__tact_dict_set_slice_slice", "signature": "(cell, ()) __tact_dict_set_slice_slice(cell d, int kl, slice k, slice v)", }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = __tact_dict_delete(d, kl, k); + return (r, (ok)); +} else { + return dict_replace_builder?(d, kl, k, begin_cell().store_slice(v)); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set { + "__tact_dict_delete", + }, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replace_slice_slice", + "signature": "(cell, (int)) __tact_dict_replace_slice_slice(cell d, int kl, slice k, slice v)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~__tact_dict_delete_get(kl, k) : d~dict_replaceget?(kl, k, begin_cell().store_slice(v).end_cell().begin_parse()); +if (ok) { + return (d, old); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set { + "__tact_dict_delete_get", + }, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_slice_slice", + "signature": "(cell, (slice)) __tact_dict_replaceget_slice_slice(cell d, int kl, slice k, slice v)", + }, { "code": { "code": "var (r, ok) = __tact_dict_get(d, kl, k); @@ -1865,6 +1946,48 @@ if (flag) { "name": "__tact_dict_set_slice_int", "signature": "(cell, ()) __tact_dict_set_slice_int(cell d, int kl, slice k, int v, int vl)", }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = __tact_dict_delete(d, kl, k); + return (r, (ok)); +} else { + return dict_replace_builder?(d, kl, k, begin_cell().store_int(v, vl)); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set { + "__tact_dict_delete", + }, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replace_slice_int", + "signature": "(cell, (int)) __tact_dict_replace_slice_int(cell d, int kl, slice k, int v, int vl)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~__tact_dict_delete_get(kl, k) : d~dict_replaceget?(kl, k, begin_cell().store_int(v, vl).end_cell().begin_parse()); +if (ok) { + return (d, old~load_int(vl)); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set { + "__tact_dict_delete_get", + }, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_slice_int", + "signature": "(cell, (int)) __tact_dict_replaceget_slice_int(cell d, int kl, slice k, int v, int vl)", + }, { "code": { "code": "var (r, ok) = __tact_dict_get(d, kl, k); @@ -1949,6 +2072,48 @@ if (flag) { "name": "__tact_dict_set_slice_uint", "signature": "(cell, ()) __tact_dict_set_slice_uint(cell d, int kl, slice k, int v, int vl)", }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = __tact_dict_delete(d, kl, k); + return (r, (ok)); +} else { + return dict_replace_builder?(d, kl, k, begin_cell().store_uint(v, vl)); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set { + "__tact_dict_delete", + }, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replace_slice_uint", + "signature": "(cell, (int)) __tact_dict_replace_slice_uint(cell d, int kl, slice k, int v, int vl)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~__tact_dict_delete_get(kl, k) : d~dict_replaceget?(kl, k, begin_cell().store_uint(v, vl).end_cell().begin_parse()); +if (ok) { + return (d, old~load_uint(vl)); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set { + "__tact_dict_delete_get", + }, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_slice_uint", + "signature": "(cell, (int)) __tact_dict_replaceget_slice_uint(cell d, int kl, slice k, int v, int vl)", + }, { "code": { "code": "var (r, ok) = __tact_dict_get_ref(d, kl, k); @@ -2034,6 +2199,50 @@ if (flag) { "name": "__tact_dict_set_slice_cell", "signature": "(cell, ()) __tact_dict_set_slice_cell(cell d, int kl, slice k, cell v)", }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = __tact_dict_delete(d, kl, k); + return (r, (ok)); +} else { + return __tact_dict_replace_ref(d, kl, k, v); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set { + "__tact_dict_delete", + "__tact_dict_replace_ref", + }, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replace_slice_cell", + "signature": "(cell, (int)) __tact_dict_replace_slice_cell(cell d, int kl, slice k, cell v)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~__tact_dict_delete_get_ref(kl, k) : d~__tact_dict_replaceget_ref(kl, k, v); +if (ok) { + return (d, old); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set { + "__tact_dict_delete_get_ref", + "__tact_dict_replaceget_ref", + }, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_slice_cell", + "signature": "(cell, (cell)) __tact_dict_replaceget_slice_cell(cell d, int kl, slice k, cell v)", + }, { "code": { "code": "var (r, ok) = udict_get?(d, kl, k); @@ -2110,6 +2319,44 @@ if (flag) { "name": "__tact_dict_set_uint_slice", "signature": "(cell, ()) __tact_dict_set_uint_slice(cell d, int kl, int k, slice v)", }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = udict_delete?(d, kl, k); + return (r, (ok)); +} else { + return udict_replace?(d, kl, k, v); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replace_uint_slice", + "signature": "(cell, (int)) __tact_dict_replace_uint_slice(cell d, int kl, int k, slice v)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~udict_delete_get?(kl, k) : d~udict_replaceget?(kl, k, v); +if (ok) { + return (d, old); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_uint_slice", + "signature": "(cell, (slice)) __tact_dict_replaceget_uint_slice(cell d, int kl, int k, slice v)", + }, { "code": { "code": "var (r, ok) = udict_get?(d, kl, k); @@ -2186,6 +2433,44 @@ if (flag) { "name": "__tact_dict_set_uint_int", "signature": "(cell, ()) __tact_dict_set_uint_int(cell d, int kl, int k, int v, int vl)", }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = udict_delete?(d, kl, k); + return (r, (ok)); +} else { + return udict_replace_builder?(d, kl, k, begin_cell().store_int(v, vl)); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replace_uint_int", + "signature": "(cell, (int)) __tact_dict_replace_uint_int(cell d, int kl, int k, int v, int vl)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~udict_delete_get?(kl, k) : d~udict_replaceget?(kl, k, begin_cell().store_int(v, vl).end_cell().begin_parse()); +if (ok) { + return (d, old~load_int(vl)); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_uint_int", + "signature": "(cell, (int)) __tact_dict_replaceget_uint_int(cell d, int kl, int k, int v, int vl)", + }, { "code": { "code": "var (r, ok) = udict_get?(d, kl, k); @@ -2262,6 +2547,44 @@ if (flag) { "name": "__tact_dict_set_uint_uint", "signature": "(cell, ()) __tact_dict_set_uint_uint(cell d, int kl, int k, int v, int vl)", }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = udict_delete?(d, kl, k); + return (r, (ok)); +} else { + return udict_replace_builder?(d, kl, k, begin_cell().store_uint(v, vl)); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replace_uint_uint", + "signature": "(cell, (int)) __tact_dict_replace_uint_uint(cell d, int kl, int k, int v, int vl)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~udict_delete_get?(kl, k) : d~udict_replaceget?(kl, k, begin_cell().store_uint(v, vl).end_cell().begin_parse()); +if (ok) { + return (d, old~load_uint(vl)); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_uint_uint", + "signature": "(cell, (int)) __tact_dict_replaceget_uint_uint(cell d, int kl, int k, int v, int vl)", + }, { "code": { "code": "var (r, ok) = udict_get_ref?(d, kl, k); @@ -2340,11 +2663,11 @@ if (flag) { }, { "code": { - "code": "var (r, ok) = idict_get?(d, kl, k); -if (ok) { - return r; + "code": "if (null?(v)) { + var (r, ok) = udict_delete?(d, kl, k); + return (r, (ok)); } else { - return null(); + return udict_replace_ref?(d, kl, k, v); }", "kind": "generic", }, @@ -2354,8 +2677,46 @@ if (ok) { "flags": Set { "inline", }, - "name": "__tact_dict_get_int_slice", - "signature": "slice __tact_dict_get_int_slice(cell d, int kl, int k)", + "name": "__tact_dict_replace_uint_cell", + "signature": "(cell, (int)) __tact_dict_replace_uint_cell(cell d, int kl, int k, cell v)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~udict_delete_get_ref?(kl, k) : d~udict_replaceget_ref?(kl, k, v); +if (ok) { + return (d, old); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_uint_cell", + "signature": "(cell, (cell)) __tact_dict_replaceget_uint_cell(cell d, int kl, int k, cell v)", + }, + { + "code": { + "code": "var (r, ok) = idict_get?(d, kl, k); +if (ok) { + return r; +} else { + return null(); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_get_int_slice", + "signature": "slice __tact_dict_get_int_slice(cell d, int kl, int k)", }, { "code": { @@ -2414,6 +2775,44 @@ if (flag) { "name": "__tact_dict_set_int_slice", "signature": "(cell, ()) __tact_dict_set_int_slice(cell d, int kl, int k, slice v)", }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = idict_delete?(d, kl, k); + return (r, (ok)); +} else { + return idict_replace?(d, kl, k, v); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replace_int_slice", + "signature": "(cell, (int)) __tact_dict_replace_int_slice(cell d, int kl, int k, slice v)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~idict_delete_get?(kl, k) : d~idict_replaceget?(kl, k, v); +if (ok) { + return (d, old); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_int_slice", + "signature": "(cell, (slice)) __tact_dict_replaceget_int_slice(cell d, int kl, int k, slice v)", + }, { "code": { "code": "var (r, ok) = idict_get?(d, kl, k); @@ -2490,6 +2889,44 @@ if (flag) { "name": "__tact_dict_set_int_int", "signature": "(cell, ()) __tact_dict_set_int_int(cell d, int kl, int k, int v, int vl)", }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = idict_delete?(d, kl, k); + return (r, (ok)); +} else { + return idict_replace_builder?(d, kl, k, begin_cell().store_int(v, vl)); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replace_int_int", + "signature": "(cell, (int)) __tact_dict_replace_int_int(cell d, int kl, int k, int v, int vl)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~idict_delete_get?(kl, k) : d~idict_replaceget?(kl, k, begin_cell().store_int(v, vl).end_cell().begin_parse()); +if (ok) { + return (d, old~load_int(vl)); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_int_int", + "signature": "(cell, (int)) __tact_dict_replaceget_int_int(cell d, int kl, int k, int v, int vl)", + }, { "code": { "code": "var (r, ok) = idict_get?(d, kl, k); @@ -2566,6 +3003,44 @@ if (flag) { "name": "__tact_dict_set_int_uint", "signature": "(cell, ()) __tact_dict_set_int_uint(cell d, int kl, int k, int v, int vl)", }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = idict_delete?(d, kl, k); + return (r, (ok)); +} else { + return idict_replace_builder?(d, kl, k, begin_cell().store_uint(v, vl)); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replace_int_uint", + "signature": "(cell, (int)) __tact_dict_replace_int_uint(cell d, int kl, int k, int v, int vl)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~idict_delete_get?(kl, k) : d~idict_replaceget?(kl, k, begin_cell().store_uint(v, vl).end_cell().begin_parse()); +if (ok) { + return (d, old~load_uint(vl)); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_int_uint", + "signature": "(cell, (int)) __tact_dict_replaceget_int_uint(cell d, int kl, int k, int v, int vl)", + }, { "code": { "code": "var (r, ok) = idict_get_ref?(d, kl, k); @@ -2642,6 +3117,44 @@ if (flag) { "name": "__tact_dict_set_int_cell", "signature": "(cell, ()) __tact_dict_set_int_cell(cell d, int kl, int k, cell v)", }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = idict_delete?(d, kl, k); + return (r, (ok)); +} else { + return idict_replace_ref?(d, kl, k, v); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replace_int_cell", + "signature": "(cell, (int)) __tact_dict_replace_int_cell(cell d, int kl, int k, cell v)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~idict_delete_get_ref?(kl, k) : d~idict_replaceget_ref?(kl, k, v); +if (ok) { + return (d, old); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_int_cell", + "signature": "(cell, (cell)) __tact_dict_replaceget_int_cell(cell d, int kl, int k, cell v)", + }, { "code": { "code": "var (r, ok) = __tact_dict_get(d, kl, k); @@ -3823,6 +4336,32 @@ return __tact_create_address(chain, hash);", "name": "__tact_dict_set_ref", "signature": "((cell), ()) __tact_dict_set_ref(cell dict, int key_len, slice index, cell value)", }, + { + "code": { + "code": "DICTREPLACEREF", + "kind": "asm", + "shuffle": "(value index dict key_len)", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set {}, + "name": "__tact_dict_replace_ref", + "signature": "((cell), (int)) __tact_dict_replace_ref(cell dict, int key_len, slice index, cell value)", + }, + { + "code": { + "code": "DICTREPLACEGETREF NULLSWAPIFNOT", + "kind": "asm", + "shuffle": "(value index dict key_len)", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set {}, + "name": "__tact_dict_replaceget_ref", + "signature": "((cell), (cell, int)) __tact_dict_replaceget_ref(cell dict, int key_len, slice index, cell value)", + }, { "code": { "code": "DICTGET NULLSWAPIFNOT", @@ -3838,7 +4377,7 @@ return __tact_create_address(chain, hash);", }, { "code": { - "code": "DICTDELGET NULLSWAPIFNOT2", + "code": "DICTDELGET NULLSWAPIFNOT", "kind": "asm", "shuffle": "(index dict key_len)", }, @@ -3849,6 +4388,19 @@ return __tact_create_address(chain, hash);", "name": "__tact_dict_delete_get", "signature": "(cell, (slice, int)) __tact_dict_delete_get(cell dict, int key_len, slice index)", }, + { + "code": { + "code": "DICTDELGETREF NULLSWAPIFNOT", + "kind": "asm", + "shuffle": "(index dict key_len)", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set {}, + "name": "__tact_dict_delete_get_ref", + "signature": "(cell, (cell, int)) __tact_dict_delete_get_ref(cell dict, int key_len, slice index)", + }, { "code": { "code": "DICTGETREF NULLSWAPIFNOT", @@ -5340,6 +5892,48 @@ if (flag) { "name": "__tact_dict_set_slice_slice", "signature": "(cell, ()) __tact_dict_set_slice_slice(cell d, int kl, slice k, slice v)", }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = __tact_dict_delete(d, kl, k); + return (r, (ok)); +} else { + return dict_replace_builder?(d, kl, k, begin_cell().store_slice(v)); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set { + "__tact_dict_delete", + }, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replace_slice_slice", + "signature": "(cell, (int)) __tact_dict_replace_slice_slice(cell d, int kl, slice k, slice v)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~__tact_dict_delete_get(kl, k) : d~dict_replaceget?(kl, k, begin_cell().store_slice(v).end_cell().begin_parse()); +if (ok) { + return (d, old); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set { + "__tact_dict_delete_get", + }, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_slice_slice", + "signature": "(cell, (slice)) __tact_dict_replaceget_slice_slice(cell d, int kl, slice k, slice v)", + }, { "code": { "code": "var (r, ok) = __tact_dict_get(d, kl, k); @@ -5424,6 +6018,48 @@ if (flag) { "name": "__tact_dict_set_slice_int", "signature": "(cell, ()) __tact_dict_set_slice_int(cell d, int kl, slice k, int v, int vl)", }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = __tact_dict_delete(d, kl, k); + return (r, (ok)); +} else { + return dict_replace_builder?(d, kl, k, begin_cell().store_int(v, vl)); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set { + "__tact_dict_delete", + }, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replace_slice_int", + "signature": "(cell, (int)) __tact_dict_replace_slice_int(cell d, int kl, slice k, int v, int vl)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~__tact_dict_delete_get(kl, k) : d~dict_replaceget?(kl, k, begin_cell().store_int(v, vl).end_cell().begin_parse()); +if (ok) { + return (d, old~load_int(vl)); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set { + "__tact_dict_delete_get", + }, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_slice_int", + "signature": "(cell, (int)) __tact_dict_replaceget_slice_int(cell d, int kl, slice k, int v, int vl)", + }, { "code": { "code": "var (r, ok) = __tact_dict_get(d, kl, k); @@ -5510,28 +6146,70 @@ if (flag) { }, { "code": { - "code": "var (r, ok) = __tact_dict_get_ref(d, kl, k); -if (ok) { - return r; + "code": "if (null?(v)) { + var (r, ok) = __tact_dict_delete(d, kl, k); + return (r, (ok)); } else { - return null(); + return dict_replace_builder?(d, kl, k, begin_cell().store_uint(v, vl)); }", "kind": "generic", }, "comment": null, "context": "stdlib", "depends": Set { - "__tact_dict_get_ref", + "__tact_dict_delete", }, "flags": Set { "inline", }, - "name": "__tact_dict_get_slice_cell", - "signature": "cell __tact_dict_get_slice_cell(cell d, int kl, slice k)", + "name": "__tact_dict_replace_slice_uint", + "signature": "(cell, (int)) __tact_dict_replace_slice_uint(cell d, int kl, slice k, int v, int vl)", }, { "code": { - "code": "var (key, value, flag) = __tact_dict_min_ref(d, kl); + "code": "var (old, ok) = null?(v) ? d~__tact_dict_delete_get(kl, k) : d~dict_replaceget?(kl, k, begin_cell().store_uint(v, vl).end_cell().begin_parse()); +if (ok) { + return (d, old~load_uint(vl)); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set { + "__tact_dict_delete_get", + }, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_slice_uint", + "signature": "(cell, (int)) __tact_dict_replaceget_slice_uint(cell d, int kl, slice k, int v, int vl)", + }, + { + "code": { + "code": "var (r, ok) = __tact_dict_get_ref(d, kl, k); +if (ok) { + return r; +} else { + return null(); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set { + "__tact_dict_get_ref", + }, + "flags": Set { + "inline", + }, + "name": "__tact_dict_get_slice_cell", + "signature": "cell __tact_dict_get_slice_cell(cell d, int kl, slice k)", + }, + { + "code": { + "code": "var (key, value, flag) = __tact_dict_min_ref(d, kl); if (flag) { return (key, value, flag); } else { @@ -5593,6 +6271,50 @@ if (flag) { "name": "__tact_dict_set_slice_cell", "signature": "(cell, ()) __tact_dict_set_slice_cell(cell d, int kl, slice k, cell v)", }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = __tact_dict_delete(d, kl, k); + return (r, (ok)); +} else { + return __tact_dict_replace_ref(d, kl, k, v); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set { + "__tact_dict_delete", + "__tact_dict_replace_ref", + }, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replace_slice_cell", + "signature": "(cell, (int)) __tact_dict_replace_slice_cell(cell d, int kl, slice k, cell v)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~__tact_dict_delete_get_ref(kl, k) : d~__tact_dict_replaceget_ref(kl, k, v); +if (ok) { + return (d, old); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set { + "__tact_dict_delete_get_ref", + "__tact_dict_replaceget_ref", + }, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_slice_cell", + "signature": "(cell, (cell)) __tact_dict_replaceget_slice_cell(cell d, int kl, slice k, cell v)", + }, { "code": { "code": "var (r, ok) = udict_get?(d, kl, k); @@ -5669,6 +6391,44 @@ if (flag) { "name": "__tact_dict_set_uint_slice", "signature": "(cell, ()) __tact_dict_set_uint_slice(cell d, int kl, int k, slice v)", }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = udict_delete?(d, kl, k); + return (r, (ok)); +} else { + return udict_replace?(d, kl, k, v); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replace_uint_slice", + "signature": "(cell, (int)) __tact_dict_replace_uint_slice(cell d, int kl, int k, slice v)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~udict_delete_get?(kl, k) : d~udict_replaceget?(kl, k, v); +if (ok) { + return (d, old); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_uint_slice", + "signature": "(cell, (slice)) __tact_dict_replaceget_uint_slice(cell d, int kl, int k, slice v)", + }, { "code": { "code": "var (r, ok) = udict_get?(d, kl, k); @@ -5745,6 +6505,44 @@ if (flag) { "name": "__tact_dict_set_uint_int", "signature": "(cell, ()) __tact_dict_set_uint_int(cell d, int kl, int k, int v, int vl)", }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = udict_delete?(d, kl, k); + return (r, (ok)); +} else { + return udict_replace_builder?(d, kl, k, begin_cell().store_int(v, vl)); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replace_uint_int", + "signature": "(cell, (int)) __tact_dict_replace_uint_int(cell d, int kl, int k, int v, int vl)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~udict_delete_get?(kl, k) : d~udict_replaceget?(kl, k, begin_cell().store_int(v, vl).end_cell().begin_parse()); +if (ok) { + return (d, old~load_int(vl)); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_uint_int", + "signature": "(cell, (int)) __tact_dict_replaceget_uint_int(cell d, int kl, int k, int v, int vl)", + }, { "code": { "code": "var (r, ok) = udict_get?(d, kl, k); @@ -5821,6 +6619,44 @@ if (flag) { "name": "__tact_dict_set_uint_uint", "signature": "(cell, ()) __tact_dict_set_uint_uint(cell d, int kl, int k, int v, int vl)", }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = udict_delete?(d, kl, k); + return (r, (ok)); +} else { + return udict_replace_builder?(d, kl, k, begin_cell().store_uint(v, vl)); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replace_uint_uint", + "signature": "(cell, (int)) __tact_dict_replace_uint_uint(cell d, int kl, int k, int v, int vl)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~udict_delete_get?(kl, k) : d~udict_replaceget?(kl, k, begin_cell().store_uint(v, vl).end_cell().begin_parse()); +if (ok) { + return (d, old~load_uint(vl)); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_uint_uint", + "signature": "(cell, (int)) __tact_dict_replaceget_uint_uint(cell d, int kl, int k, int v, int vl)", + }, { "code": { "code": "var (r, ok) = udict_get_ref?(d, kl, k); @@ -5897,6 +6733,44 @@ if (flag) { "name": "__tact_dict_set_uint_cell", "signature": "(cell, ()) __tact_dict_set_uint_cell(cell d, int kl, int k, cell v)", }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = udict_delete?(d, kl, k); + return (r, (ok)); +} else { + return udict_replace_ref?(d, kl, k, v); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replace_uint_cell", + "signature": "(cell, (int)) __tact_dict_replace_uint_cell(cell d, int kl, int k, cell v)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~udict_delete_get_ref?(kl, k) : d~udict_replaceget_ref?(kl, k, v); +if (ok) { + return (d, old); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_uint_cell", + "signature": "(cell, (cell)) __tact_dict_replaceget_uint_cell(cell d, int kl, int k, cell v)", + }, { "code": { "code": "var (r, ok) = idict_get?(d, kl, k); @@ -5973,6 +6847,44 @@ if (flag) { "name": "__tact_dict_set_int_slice", "signature": "(cell, ()) __tact_dict_set_int_slice(cell d, int kl, int k, slice v)", }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = idict_delete?(d, kl, k); + return (r, (ok)); +} else { + return idict_replace?(d, kl, k, v); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replace_int_slice", + "signature": "(cell, (int)) __tact_dict_replace_int_slice(cell d, int kl, int k, slice v)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~idict_delete_get?(kl, k) : d~idict_replaceget?(kl, k, v); +if (ok) { + return (d, old); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_int_slice", + "signature": "(cell, (slice)) __tact_dict_replaceget_int_slice(cell d, int kl, int k, slice v)", + }, { "code": { "code": "var (r, ok) = idict_get?(d, kl, k); @@ -6049,6 +6961,44 @@ if (flag) { "name": "__tact_dict_set_int_int", "signature": "(cell, ()) __tact_dict_set_int_int(cell d, int kl, int k, int v, int vl)", }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = idict_delete?(d, kl, k); + return (r, (ok)); +} else { + return idict_replace_builder?(d, kl, k, begin_cell().store_int(v, vl)); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replace_int_int", + "signature": "(cell, (int)) __tact_dict_replace_int_int(cell d, int kl, int k, int v, int vl)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~idict_delete_get?(kl, k) : d~idict_replaceget?(kl, k, begin_cell().store_int(v, vl).end_cell().begin_parse()); +if (ok) { + return (d, old~load_int(vl)); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_int_int", + "signature": "(cell, (int)) __tact_dict_replaceget_int_int(cell d, int kl, int k, int v, int vl)", + }, { "code": { "code": "var (r, ok) = idict_get?(d, kl, k); @@ -6125,6 +7075,44 @@ if (flag) { "name": "__tact_dict_set_int_uint", "signature": "(cell, ()) __tact_dict_set_int_uint(cell d, int kl, int k, int v, int vl)", }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = idict_delete?(d, kl, k); + return (r, (ok)); +} else { + return idict_replace_builder?(d, kl, k, begin_cell().store_uint(v, vl)); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replace_int_uint", + "signature": "(cell, (int)) __tact_dict_replace_int_uint(cell d, int kl, int k, int v, int vl)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~idict_delete_get?(kl, k) : d~idict_replaceget?(kl, k, begin_cell().store_uint(v, vl).end_cell().begin_parse()); +if (ok) { + return (d, old~load_uint(vl)); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_int_uint", + "signature": "(cell, (int)) __tact_dict_replaceget_int_uint(cell d, int kl, int k, int v, int vl)", + }, { "code": { "code": "var (r, ok) = idict_get_ref?(d, kl, k); @@ -6201,6 +7189,44 @@ if (flag) { "name": "__tact_dict_set_int_cell", "signature": "(cell, ()) __tact_dict_set_int_cell(cell d, int kl, int k, cell v)", }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = idict_delete?(d, kl, k); + return (r, (ok)); +} else { + return idict_replace_ref?(d, kl, k, v); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replace_int_cell", + "signature": "(cell, (int)) __tact_dict_replace_int_cell(cell d, int kl, int k, cell v)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~idict_delete_get_ref?(kl, k) : d~idict_replaceget_ref?(kl, k, v); +if (ok) { + return (d, old); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_int_cell", + "signature": "(cell, (cell)) __tact_dict_replaceget_int_cell(cell d, int kl, int k, cell v)", + }, { "code": { "code": "var (r, ok) = __tact_dict_get(d, kl, k); @@ -7382,6 +8408,32 @@ return __tact_create_address(chain, hash);", "name": "__tact_dict_set_ref", "signature": "((cell), ()) __tact_dict_set_ref(cell dict, int key_len, slice index, cell value)", }, + { + "code": { + "code": "DICTREPLACEREF", + "kind": "asm", + "shuffle": "(value index dict key_len)", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set {}, + "name": "__tact_dict_replace_ref", + "signature": "((cell), (int)) __tact_dict_replace_ref(cell dict, int key_len, slice index, cell value)", + }, + { + "code": { + "code": "DICTREPLACEGETREF NULLSWAPIFNOT", + "kind": "asm", + "shuffle": "(value index dict key_len)", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set {}, + "name": "__tact_dict_replaceget_ref", + "signature": "((cell), (cell, int)) __tact_dict_replaceget_ref(cell dict, int key_len, slice index, cell value)", + }, { "code": { "code": "DICTGET NULLSWAPIFNOT", @@ -7397,7 +8449,7 @@ return __tact_create_address(chain, hash);", }, { "code": { - "code": "DICTDELGET NULLSWAPIFNOT2", + "code": "DICTDELGET NULLSWAPIFNOT", "kind": "asm", "shuffle": "(index dict key_len)", }, @@ -7408,6 +8460,19 @@ return __tact_create_address(chain, hash);", "name": "__tact_dict_delete_get", "signature": "(cell, (slice, int)) __tact_dict_delete_get(cell dict, int key_len, slice index)", }, + { + "code": { + "code": "DICTDELGETREF NULLSWAPIFNOT", + "kind": "asm", + "shuffle": "(index dict key_len)", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set {}, + "name": "__tact_dict_delete_get_ref", + "signature": "(cell, (cell, int)) __tact_dict_delete_get_ref(cell dict, int key_len, slice index)", + }, { "code": { "code": "DICTGETREF NULLSWAPIFNOT", @@ -8899,6 +9964,48 @@ if (flag) { "name": "__tact_dict_set_slice_slice", "signature": "(cell, ()) __tact_dict_set_slice_slice(cell d, int kl, slice k, slice v)", }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = __tact_dict_delete(d, kl, k); + return (r, (ok)); +} else { + return dict_replace_builder?(d, kl, k, begin_cell().store_slice(v)); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set { + "__tact_dict_delete", + }, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replace_slice_slice", + "signature": "(cell, (int)) __tact_dict_replace_slice_slice(cell d, int kl, slice k, slice v)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~__tact_dict_delete_get(kl, k) : d~dict_replaceget?(kl, k, begin_cell().store_slice(v).end_cell().begin_parse()); +if (ok) { + return (d, old); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set { + "__tact_dict_delete_get", + }, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_slice_slice", + "signature": "(cell, (slice)) __tact_dict_replaceget_slice_slice(cell d, int kl, slice k, slice v)", + }, { "code": { "code": "var (r, ok) = __tact_dict_get(d, kl, k); @@ -8983,6 +10090,48 @@ if (flag) { "name": "__tact_dict_set_slice_int", "signature": "(cell, ()) __tact_dict_set_slice_int(cell d, int kl, slice k, int v, int vl)", }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = __tact_dict_delete(d, kl, k); + return (r, (ok)); +} else { + return dict_replace_builder?(d, kl, k, begin_cell().store_int(v, vl)); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set { + "__tact_dict_delete", + }, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replace_slice_int", + "signature": "(cell, (int)) __tact_dict_replace_slice_int(cell d, int kl, slice k, int v, int vl)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~__tact_dict_delete_get(kl, k) : d~dict_replaceget?(kl, k, begin_cell().store_int(v, vl).end_cell().begin_parse()); +if (ok) { + return (d, old~load_int(vl)); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set { + "__tact_dict_delete_get", + }, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_slice_int", + "signature": "(cell, (int)) __tact_dict_replaceget_slice_int(cell d, int kl, slice k, int v, int vl)", + }, { "code": { "code": "var (r, ok) = __tact_dict_get(d, kl, k); @@ -9067,6 +10216,48 @@ if (flag) { "name": "__tact_dict_set_slice_uint", "signature": "(cell, ()) __tact_dict_set_slice_uint(cell d, int kl, slice k, int v, int vl)", }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = __tact_dict_delete(d, kl, k); + return (r, (ok)); +} else { + return dict_replace_builder?(d, kl, k, begin_cell().store_uint(v, vl)); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set { + "__tact_dict_delete", + }, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replace_slice_uint", + "signature": "(cell, (int)) __tact_dict_replace_slice_uint(cell d, int kl, slice k, int v, int vl)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~__tact_dict_delete_get(kl, k) : d~dict_replaceget?(kl, k, begin_cell().store_uint(v, vl).end_cell().begin_parse()); +if (ok) { + return (d, old~load_uint(vl)); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set { + "__tact_dict_delete_get", + }, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_slice_uint", + "signature": "(cell, (int)) __tact_dict_replaceget_slice_uint(cell d, int kl, slice k, int v, int vl)", + }, { "code": { "code": "var (r, ok) = __tact_dict_get_ref(d, kl, k); @@ -9106,51 +10297,95 @@ if (flag) { "flags": Set { "inline", }, - "name": "__tact_dict_min_slice_cell", - "signature": "(slice, cell, int) __tact_dict_min_slice_cell(cell d, int kl)", + "name": "__tact_dict_min_slice_cell", + "signature": "(slice, cell, int) __tact_dict_min_slice_cell(cell d, int kl)", + }, + { + "code": { + "code": "var (key, value, flag) = __tact_dict_next(d, kl, pivot); +if (flag) { + return (key, value~load_ref(), flag); +} else { + return (null(), null(), flag); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set { + "__tact_dict_next", + }, + "flags": Set { + "inline", + }, + "name": "__tact_dict_next_slice_cell", + "signature": "(slice, cell, int) __tact_dict_next_slice_cell(cell d, int kl, slice pivot)", + }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = __tact_dict_delete(d, kl, k); + return (r, ()); +} else { + return __tact_dict_set_ref(d, kl, k, v); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set { + "__tact_dict_delete", + "__tact_dict_set_ref", + }, + "flags": Set { + "inline", + }, + "name": "__tact_dict_set_slice_cell", + "signature": "(cell, ()) __tact_dict_set_slice_cell(cell d, int kl, slice k, cell v)", }, { "code": { - "code": "var (key, value, flag) = __tact_dict_next(d, kl, pivot); -if (flag) { - return (key, value~load_ref(), flag); + "code": "if (null?(v)) { + var (r, ok) = __tact_dict_delete(d, kl, k); + return (r, (ok)); } else { - return (null(), null(), flag); + return __tact_dict_replace_ref(d, kl, k, v); }", "kind": "generic", }, "comment": null, "context": "stdlib", "depends": Set { - "__tact_dict_next", + "__tact_dict_delete", + "__tact_dict_replace_ref", }, "flags": Set { "inline", }, - "name": "__tact_dict_next_slice_cell", - "signature": "(slice, cell, int) __tact_dict_next_slice_cell(cell d, int kl, slice pivot)", + "name": "__tact_dict_replace_slice_cell", + "signature": "(cell, (int)) __tact_dict_replace_slice_cell(cell d, int kl, slice k, cell v)", }, { "code": { - "code": "if (null?(v)) { - var (r, ok) = __tact_dict_delete(d, kl, k); - return (r, ()); + "code": "var (old, ok) = null?(v) ? d~__tact_dict_delete_get_ref(kl, k) : d~__tact_dict_replaceget_ref(kl, k, v); +if (ok) { + return (d, old); } else { - return __tact_dict_set_ref(d, kl, k, v); + return (d, null()); }", "kind": "generic", }, "comment": null, "context": "stdlib", "depends": Set { - "__tact_dict_delete", - "__tact_dict_set_ref", + "__tact_dict_delete_get_ref", + "__tact_dict_replaceget_ref", }, "flags": Set { "inline", }, - "name": "__tact_dict_set_slice_cell", - "signature": "(cell, ()) __tact_dict_set_slice_cell(cell d, int kl, slice k, cell v)", + "name": "__tact_dict_replaceget_slice_cell", + "signature": "(cell, (cell)) __tact_dict_replaceget_slice_cell(cell d, int kl, slice k, cell v)", }, { "code": { @@ -9228,6 +10463,44 @@ if (flag) { "name": "__tact_dict_set_uint_slice", "signature": "(cell, ()) __tact_dict_set_uint_slice(cell d, int kl, int k, slice v)", }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = udict_delete?(d, kl, k); + return (r, (ok)); +} else { + return udict_replace?(d, kl, k, v); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replace_uint_slice", + "signature": "(cell, (int)) __tact_dict_replace_uint_slice(cell d, int kl, int k, slice v)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~udict_delete_get?(kl, k) : d~udict_replaceget?(kl, k, v); +if (ok) { + return (d, old); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_uint_slice", + "signature": "(cell, (slice)) __tact_dict_replaceget_uint_slice(cell d, int kl, int k, slice v)", + }, { "code": { "code": "var (r, ok) = udict_get?(d, kl, k); @@ -9304,6 +10577,44 @@ if (flag) { "name": "__tact_dict_set_uint_int", "signature": "(cell, ()) __tact_dict_set_uint_int(cell d, int kl, int k, int v, int vl)", }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = udict_delete?(d, kl, k); + return (r, (ok)); +} else { + return udict_replace_builder?(d, kl, k, begin_cell().store_int(v, vl)); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replace_uint_int", + "signature": "(cell, (int)) __tact_dict_replace_uint_int(cell d, int kl, int k, int v, int vl)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~udict_delete_get?(kl, k) : d~udict_replaceget?(kl, k, begin_cell().store_int(v, vl).end_cell().begin_parse()); +if (ok) { + return (d, old~load_int(vl)); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_uint_int", + "signature": "(cell, (int)) __tact_dict_replaceget_uint_int(cell d, int kl, int k, int v, int vl)", + }, { "code": { "code": "var (r, ok) = udict_get?(d, kl, k); @@ -9380,6 +10691,44 @@ if (flag) { "name": "__tact_dict_set_uint_uint", "signature": "(cell, ()) __tact_dict_set_uint_uint(cell d, int kl, int k, int v, int vl)", }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = udict_delete?(d, kl, k); + return (r, (ok)); +} else { + return udict_replace_builder?(d, kl, k, begin_cell().store_uint(v, vl)); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replace_uint_uint", + "signature": "(cell, (int)) __tact_dict_replace_uint_uint(cell d, int kl, int k, int v, int vl)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~udict_delete_get?(kl, k) : d~udict_replaceget?(kl, k, begin_cell().store_uint(v, vl).end_cell().begin_parse()); +if (ok) { + return (d, old~load_uint(vl)); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_uint_uint", + "signature": "(cell, (int)) __tact_dict_replaceget_uint_uint(cell d, int kl, int k, int v, int vl)", + }, { "code": { "code": "var (r, ok) = udict_get_ref?(d, kl, k); @@ -9456,6 +10805,44 @@ if (flag) { "name": "__tact_dict_set_uint_cell", "signature": "(cell, ()) __tact_dict_set_uint_cell(cell d, int kl, int k, cell v)", }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = udict_delete?(d, kl, k); + return (r, (ok)); +} else { + return udict_replace_ref?(d, kl, k, v); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replace_uint_cell", + "signature": "(cell, (int)) __tact_dict_replace_uint_cell(cell d, int kl, int k, cell v)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~udict_delete_get_ref?(kl, k) : d~udict_replaceget_ref?(kl, k, v); +if (ok) { + return (d, old); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_uint_cell", + "signature": "(cell, (cell)) __tact_dict_replaceget_uint_cell(cell d, int kl, int k, cell v)", + }, { "code": { "code": "var (r, ok) = idict_get?(d, kl, k); @@ -9532,6 +10919,44 @@ if (flag) { "name": "__tact_dict_set_int_slice", "signature": "(cell, ()) __tact_dict_set_int_slice(cell d, int kl, int k, slice v)", }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = idict_delete?(d, kl, k); + return (r, (ok)); +} else { + return idict_replace?(d, kl, k, v); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replace_int_slice", + "signature": "(cell, (int)) __tact_dict_replace_int_slice(cell d, int kl, int k, slice v)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~idict_delete_get?(kl, k) : d~idict_replaceget?(kl, k, v); +if (ok) { + return (d, old); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_int_slice", + "signature": "(cell, (slice)) __tact_dict_replaceget_int_slice(cell d, int kl, int k, slice v)", + }, { "code": { "code": "var (r, ok) = idict_get?(d, kl, k); @@ -9608,6 +11033,44 @@ if (flag) { "name": "__tact_dict_set_int_int", "signature": "(cell, ()) __tact_dict_set_int_int(cell d, int kl, int k, int v, int vl)", }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = idict_delete?(d, kl, k); + return (r, (ok)); +} else { + return idict_replace_builder?(d, kl, k, begin_cell().store_int(v, vl)); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replace_int_int", + "signature": "(cell, (int)) __tact_dict_replace_int_int(cell d, int kl, int k, int v, int vl)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~idict_delete_get?(kl, k) : d~idict_replaceget?(kl, k, begin_cell().store_int(v, vl).end_cell().begin_parse()); +if (ok) { + return (d, old~load_int(vl)); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_int_int", + "signature": "(cell, (int)) __tact_dict_replaceget_int_int(cell d, int kl, int k, int v, int vl)", + }, { "code": { "code": "var (r, ok) = idict_get?(d, kl, k); @@ -9684,6 +11147,44 @@ if (flag) { "name": "__tact_dict_set_int_uint", "signature": "(cell, ()) __tact_dict_set_int_uint(cell d, int kl, int k, int v, int vl)", }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = idict_delete?(d, kl, k); + return (r, (ok)); +} else { + return idict_replace_builder?(d, kl, k, begin_cell().store_uint(v, vl)); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replace_int_uint", + "signature": "(cell, (int)) __tact_dict_replace_int_uint(cell d, int kl, int k, int v, int vl)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~idict_delete_get?(kl, k) : d~idict_replaceget?(kl, k, begin_cell().store_uint(v, vl).end_cell().begin_parse()); +if (ok) { + return (d, old~load_uint(vl)); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_int_uint", + "signature": "(cell, (int)) __tact_dict_replaceget_int_uint(cell d, int kl, int k, int v, int vl)", + }, { "code": { "code": "var (r, ok) = idict_get_ref?(d, kl, k); @@ -9760,6 +11261,44 @@ if (flag) { "name": "__tact_dict_set_int_cell", "signature": "(cell, ()) __tact_dict_set_int_cell(cell d, int kl, int k, cell v)", }, + { + "code": { + "code": "if (null?(v)) { + var (r, ok) = idict_delete?(d, kl, k); + return (r, (ok)); +} else { + return idict_replace_ref?(d, kl, k, v); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replace_int_cell", + "signature": "(cell, (int)) __tact_dict_replace_int_cell(cell d, int kl, int k, cell v)", + }, + { + "code": { + "code": "var (old, ok) = null?(v) ? d~idict_delete_get_ref?(kl, k) : d~idict_replaceget_ref?(kl, k, v); +if (ok) { + return (d, old); +} else { + return (d, null()); +}", + "kind": "generic", + }, + "comment": null, + "context": "stdlib", + "depends": Set {}, + "flags": Set { + "inline", + }, + "name": "__tact_dict_replaceget_int_cell", + "signature": "(cell, (cell)) __tact_dict_replaceget_int_cell(cell d, int kl, int k, cell v)", + }, { "code": { "code": "var (r, ok) = __tact_dict_get(d, kl, k); diff --git a/src/generator/writers/writeStdlib.ts b/src/generator/writers/writeStdlib.ts index 25e5e9b03..5ca630c6d 100644 --- a/src/generator/writers/writeStdlib.ts +++ b/src/generator/writers/writeStdlib.ts @@ -81,7 +81,9 @@ 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(${ctx.used( + `__tact_verify_address`, + )}(address)); `); }); }); @@ -185,6 +187,25 @@ export function writeStdlib(ctx: WriterContext): void { ctx.asm("(value index dict key_len)", "DICTSETREF"); }); + ctx.fun("__tact_dict_replace_ref", () => { + ctx.signature( + `((cell), (int)) __tact_dict_replace_ref(cell dict, int key_len, slice index, cell value)`, + ); + ctx.context("stdlib"); + ctx.asm("(value index dict key_len)", "DICTREPLACEREF"); + }); + + ctx.fun("__tact_dict_replaceget_ref", () => { + ctx.signature( + `((cell), (cell, int)) __tact_dict_replaceget_ref(cell dict, int key_len, slice index, cell value)`, + ); + ctx.context("stdlib"); + ctx.asm( + "(value index dict key_len)", + "DICTREPLACEGETREF NULLSWAPIFNOT", + ); + }); + ctx.fun("__tact_dict_get", () => { ctx.signature( `(slice, int) __tact_dict_get(cell dict, int key_len, slice index)`, @@ -198,7 +219,15 @@ export function writeStdlib(ctx: WriterContext): void { `(cell, (slice, int)) __tact_dict_delete_get(cell dict, int key_len, slice index)`, ); ctx.context("stdlib"); - ctx.asm("(index dict key_len)", "DICTDELGET NULLSWAPIFNOT2"); + ctx.asm("(index dict key_len)", "DICTDELGET NULLSWAPIFNOT"); + }); + + ctx.fun("__tact_dict_delete_get_ref", () => { + ctx.signature( + `(cell, (cell, int)) __tact_dict_delete_get_ref(cell dict, int key_len, slice index)`, + ); + ctx.context("stdlib"); + ctx.asm("(index dict key_len)", "DICTDELGETREF NULLSWAPIFNOT"); }); ctx.fun("__tact_dict_get_ref", () => { @@ -240,7 +269,9 @@ export function writeStdlib(ctx: WriterContext): void { ctx.context("stdlib"); ctx.body(() => { ctx.write(` - var (key, value, flag) = ${ctx.used("__tact_dict_next")}(dict, key_len, pivot); + var (key, value, flag) = ${ctx.used( + "__tact_dict_next", + )}(dict, key_len, pivot); if (flag) { return (key, value~load_ref(), flag); } else { @@ -277,9 +308,13 @@ export function writeStdlib(ctx: WriterContext): void { ctx.body(() => { ctx.write(` if (value) { - ${ctx.used("__tact_debug_str")}("true", debug_print_1, debug_print_2); + ${ctx.used( + "__tact_debug_str", + )}("true", debug_print_1, debug_print_2); } else { - ${ctx.used("__tact_debug_str")}("false", debug_print_1, debug_print_2); + ${ctx.used( + "__tact_debug_str", + )}("false", debug_print_1, debug_print_2); } `); }); @@ -343,10 +378,18 @@ export function writeStdlib(ctx: WriterContext): void { int n = (bs1 << 16) | (bs2 << 8) | bs3; res = res - .store_slice(${ctx.used("__tact_preload_offset")}(chars, ((n >> 18) & 63) * 8, 8)) - .store_slice(${ctx.used("__tact_preload_offset")}(chars, ((n >> 12) & 63) * 8, 8)) - .store_slice(${ctx.used("__tact_preload_offset")}(chars, ((n >> 6) & 63) * 8, 8)) - .store_slice(${ctx.used("__tact_preload_offset")}(chars, ((n ) & 63) * 8, 8)); + .store_slice(${ctx.used( + "__tact_preload_offset", + )}(chars, ((n >> 18) & 63) * 8, 8)) + .store_slice(${ctx.used( + "__tact_preload_offset", + )}(chars, ((n >> 12) & 63) * 8, 8)) + .store_slice(${ctx.used( + "__tact_preload_offset", + )}(chars, ((n >> 6) & 63) * 8, 8)) + .store_slice(${ctx.used( + "__tact_preload_offset", + )}(chars, ((n ) & 63) * 8, 8)); } return res.end_cell().begin_parse(); @@ -367,13 +410,17 @@ export function writeStdlib(ctx: WriterContext): void { .store_uint(hash, 256) .end_cell().begin_parse(); - slice checksum = ${ctx.used("__tact_crc16")}(user_friendly_address); + slice checksum = ${ctx.used( + "__tact_crc16", + )}(user_friendly_address); slice user_friendly_address_with_checksum = begin_cell() .store_slice(user_friendly_address) .store_slice(checksum) .end_cell().begin_parse(); - return ${ctx.used("__tact_base64_encode")}(user_friendly_address_with_checksum); + return ${ctx.used( + "__tact_base64_encode", + )}(user_friendly_address_with_checksum); `); }); }); @@ -386,7 +433,9 @@ export function writeStdlib(ctx: WriterContext): void { ctx.context("stdlib"); ctx.body(() => { ctx.write(` - ${ctx.used("__tact_debug_str")}(${ctx.used("__tact_address_to_user_friendly")}(address), debug_print_1, debug_print_2); + ${ctx.used("__tact_debug_str")}(${ctx.used( + "__tact_address_to_user_friendly", + )}(address), debug_print_1, debug_print_2); `); }); }); @@ -507,16 +556,22 @@ export function writeStdlib(ctx: WriterContext): void { ctx.context("stdlib"); ctx.body(() => { ctx.write(` - (slice key, slice value, int flag) = ${ctx.used("__tact_dict_min")}(a, kl); + (slice key, slice value, int flag) = ${ctx.used( + "__tact_dict_min", + )}(a, kl); while (flag) { - (slice value_b, int flag_b) = b~${ctx.used("__tact_dict_delete_get")}(kl, key); + (slice value_b, int flag_b) = b~${ctx.used( + "__tact_dict_delete_get", + )}(kl, key); ifnot (flag_b) { return 0; } ifnot (value.slice_hash() == value_b.slice_hash()) { return 0; } - (key, value, flag) = ${ctx.used("__tact_dict_next")}(a, kl, key); + (key, value, flag) = ${ctx.used( + "__tact_dict_next", + )}(a, kl, key); } return null?(b); `); @@ -778,7 +833,9 @@ export function writeStdlib(ctx: WriterContext): void { args.push(`X${j}`); } ctx.signature( - `forall ${args.join(", ")} -> tuple __tact_tuple_create_${i}((${args.join(", ")}) v)`, + `forall ${args.join( + ", ", + )} -> tuple __tact_tuple_create_${i}((${args.join(", ")}) v)`, ); ctx.context("stdlib"); ctx.asm("", `${i} TUPLE`); @@ -789,7 +846,9 @@ export function writeStdlib(ctx: WriterContext): void { args.push(`X${j}`); } ctx.signature( - `forall ${args.join(", ")} -> (${args.join(", ")}) __tact_tuple_destroy_${i}(tuple v)`, + `forall ${args.join(", ")} -> (${args.join( + ", ", + )}) __tact_tuple_destroy_${i}(tuple v)`, ); ctx.context("stdlib"); ctx.asm("", `${i} UNTUPLE`); @@ -806,7 +865,9 @@ export function writeStdlib(ctx: WriterContext): void { ctx.context("stdlib"); ctx.body(() => { ctx.write(` - return ${ctx.used("__tact_string_builder_start")}(begin_cell().store_uint(0, 32)); + return ${ctx.used( + "__tact_string_builder_start", + )}(begin_cell().store_uint(0, 32)); `); }); }); @@ -817,7 +878,9 @@ export function writeStdlib(ctx: WriterContext): void { ctx.context("stdlib"); ctx.body(() => { ctx.write(` - return ${ctx.used("__tact_string_builder_start")}(begin_cell().store_uint(0, 8)); + return ${ctx.used( + "__tact_string_builder_start", + )}(begin_cell().store_uint(0, 8)); `); }); }); @@ -867,7 +930,9 @@ export function writeStdlib(ctx: WriterContext): void { ctx.context("stdlib"); ctx.body(() => { ctx.write(` - return ${ctx.used("__tact_string_builder_end")}(builders).begin_parse(); + return ${ctx.used( + "__tact_string_builder_end", + )}(builders).begin_parse(); `); }); }); @@ -1075,6 +1140,8 @@ export function writeStdlib(ctx: WriterContext): void { genTactDictGetMin(ctx, key, val); genTactDictGetNext(ctx, key, val); genTactDictSet(ctx, key, val); + genTactDictReplace(ctx, key, val); + genTactDictReplaceGet(ctx, key, val); } } for (const key of keyTypes) { @@ -1387,3 +1454,171 @@ function genTactDictGetNext( }); }); } + +function genTactDictReplace( + ctx: WriterContext, + key: KeyType, + value: ValType, +): void { + const signatureKeyType = key === "uint" ? "int" : key; + const signatureValueType = value === "uint" ? "int" : value; + const valBitsArg = () => { + switch (value) { + case "slice": + case "cell": + return ""; + case "uint": + case "int": + return ", int vl"; + } + }; + const dictDel = () => { + switch (key) { + case "slice": + return ctx.used("__tact_dict_delete"); + case "uint": + return "udict_delete?"; + case "int": + return "idict_delete?"; + } + }; + const returnExpr = () => { + switch (`${key}:${value}`) { + case "int:int": + return "idict_replace_builder?(d, kl, k, begin_cell().store_int(v, vl))"; + case "int:uint": + return "idict_replace_builder?(d, kl, k, begin_cell().store_uint(v, vl))"; + case "uint:int": + return "udict_replace_builder?(d, kl, k, begin_cell().store_int(v, vl))"; + case "uint:uint": + return "udict_replace_builder?(d, kl, k, begin_cell().store_uint(v, vl))"; + case "slice:int": + return "dict_replace_builder?(d, kl, k, begin_cell().store_int(v, vl))"; + case "slice:uint": + return "dict_replace_builder?(d, kl, k, begin_cell().store_uint(v, vl))"; + case "int:cell": + return "idict_replace_ref?(d, kl, k, v)"; + case "uint:cell": + return "udict_replace_ref?(d, kl, k, v)"; + case "int:slice": + return "idict_replace?(d, kl, k, v)"; + case "uint:slice": + return "udict_replace?(d, kl, k, v)"; + case "slice:cell": + return `${ctx.used("__tact_dict_replace_ref")}(d, kl, k, v)`; + case "slice:slice": + return "dict_replace_builder?(d, kl, k, begin_cell().store_slice(v))"; + default: + throwInternalCompilerError( + `Unprocessed combination of key/value types ${key}/${value} in dict replace operation`, + ); + } + }; + ctx.fun(`__tact_dict_replace_${key}_${value}`, () => { + ctx.signature( + `(cell, (int)) __tact_dict_replace_${key}_${value}(cell d, int kl, ${signatureKeyType} k, ${signatureValueType} v${valBitsArg()})`, + ); + ctx.flag("inline"); + ctx.context("stdlib"); + ctx.body(() => { + ctx.write(` + if (null?(v)) { + var (r, ok) = ${dictDel()}(d, kl, k); + return (r, (ok)); + } else { + return ${returnExpr()}; + } + `); + }); + }); +} + +function genTactDictReplaceGet( + ctx: WriterContext, + key: KeyType, + value: ValType, +): void { + const signatureKeyType = key === "uint" ? "int" : key; + const signatureValueType = value === "uint" ? "int" : value; + const valBitsArg = () => { + switch (value) { + case "slice": + case "cell": + return ""; + case "uint": + case "int": + return ", int vl"; + } + }; + const dictDelGet = () => { + const cellSuffix = value === "cell" ? "_ref" : ""; + switch (key) { + case "slice": + return ctx.used(`__tact_dict_delete_get${cellSuffix}`); + case "uint": + return `udict_delete_get${cellSuffix}?`; + case "int": + return `idict_delete_get${cellSuffix}?`; + } + }; + const returnExpr = () => { + switch (`${key}:${value}`) { + case "int:int": + return "d~idict_replaceget?(kl, k, begin_cell().store_int(v, vl).end_cell().begin_parse())"; + case "int:uint": + return "d~idict_replaceget?(kl, k, begin_cell().store_uint(v, vl).end_cell().begin_parse())"; + case "uint:int": + return "d~udict_replaceget?(kl, k, begin_cell().store_int(v, vl).end_cell().begin_parse())"; + case "uint:uint": + return "d~udict_replaceget?(kl, k, begin_cell().store_uint(v, vl).end_cell().begin_parse())"; + case "slice:int": + return "d~dict_replaceget?(kl, k, begin_cell().store_int(v, vl).end_cell().begin_parse())"; + case "slice:uint": + return "d~dict_replaceget?(kl, k, begin_cell().store_uint(v, vl).end_cell().begin_parse())"; + case "int:cell": + return "d~idict_replaceget_ref?(kl, k, v)"; + case "uint:cell": + return "d~udict_replaceget_ref?(kl, k, v)"; + case "int:slice": + return "d~idict_replaceget?(kl, k, v)"; + case "uint:slice": + return "d~udict_replaceget?(kl, k, v)"; + case "slice:cell": + return `d~${ctx.used("__tact_dict_replaceget_ref")}(kl, k, v)`; + case "slice:slice": + return "d~dict_replaceget?(kl, k, begin_cell().store_slice(v).end_cell().begin_parse())"; + default: + throwInternalCompilerError( + `Unprocessed combination of key/value types ${key}/${value} in dict replaceGet operation`, + ); + } + }; + const parseExpr = () => { + switch (value) { + case "slice": + case "cell": + return "old"; + case "uint": + return "old~load_uint(vl)"; + case "int": + return "old~load_int(vl)"; + } + }; + ctx.fun(`__tact_dict_replaceget_${key}_${value}`, () => { + ctx.signature( + `(cell, (${signatureValueType})) __tact_dict_replaceget_${key}_${value}(cell d, int kl, ${signatureKeyType} k, ${signatureValueType} v${valBitsArg()})`, + ); + ctx.flag("inline"); + ctx.context("stdlib"); + ctx.body(() => { + ctx.write(` + var (old, ok) = null?(v) ? d~${dictDelGet()}(kl, k) : ${returnExpr()}; + if (ok) { + return (d, ${parseExpr()}); + } else { + return (d, null()); + } + `); + }); + }); +} diff --git a/src/imports/stdlib.ts b/src/imports/stdlib.ts index c50def19b..defde7255 100644 --- a/src/imports/stdlib.ts +++ b/src/imports/stdlib.ts @@ -598,126 +598,162 @@ files['stdlib.fc'] = 'bnQpIHVkaWN0X2RlbGV0ZV9nZXQ/KGNlbGwgZGljdCwgaW50IGtleV9sZW4sIGludCBpbmRleCkgYXNtKGluZGV4IGRpY3Qga2V5X2xlbikgIkRJQ1RVREVMR0VUIiAi' + 'TlVMTFNXQVBJRk5PVCI7CihjZWxsLCAoc2xpY2UsIGludCkpIH5pZGljdF9kZWxldGVfZ2V0PyhjZWxsIGRpY3QsIGludCBrZXlfbGVuLCBpbnQgaW5kZXgpIGFzbShp' + 'bmRleCBkaWN0IGtleV9sZW4pICJESUNUSURFTEdFVCIgIk5VTExTV0FQSUZOT1QiOwooY2VsbCwgKHNsaWNlLCBpbnQpKSB+dWRpY3RfZGVsZXRlX2dldD8oY2VsbCBk' + - 'aWN0LCBpbnQga2V5X2xlbiwgaW50IGluZGV4KSBhc20oaW5kZXggZGljdCBrZXlfbGVuKSAiRElDVFVERUxHRVQiICJOVUxMU1dBUElGTk9UIjsKY2VsbCB1ZGljdF9z' + - 'ZXQoY2VsbCBkaWN0LCBpbnQga2V5X2xlbiwgaW50IGluZGV4LCBzbGljZSB2YWx1ZSkgYXNtKHZhbHVlIGluZGV4IGRpY3Qga2V5X2xlbikgIkRJQ1RVU0VUIjsKKGNl' + - 'bGwsICgpKSB+dWRpY3Rfc2V0KGNlbGwgZGljdCwgaW50IGtleV9sZW4sIGludCBpbmRleCwgc2xpY2UgdmFsdWUpIGFzbSh2YWx1ZSBpbmRleCBkaWN0IGtleV9sZW4p' + - 'ICJESUNUVVNFVCI7CmNlbGwgaWRpY3Rfc2V0KGNlbGwgZGljdCwgaW50IGtleV9sZW4sIGludCBpbmRleCwgc2xpY2UgdmFsdWUpIGFzbSh2YWx1ZSBpbmRleCBkaWN0' + - 'IGtleV9sZW4pICJESUNUSVNFVCI7CihjZWxsLCAoKSkgfmlkaWN0X3NldChjZWxsIGRpY3QsIGludCBrZXlfbGVuLCBpbnQgaW5kZXgsIHNsaWNlIHZhbHVlKSBhc20o' + - 'dmFsdWUgaW5kZXggZGljdCBrZXlfbGVuKSAiRElDVElTRVQiOwpjZWxsIGRpY3Rfc2V0KGNlbGwgZGljdCwgaW50IGtleV9sZW4sIHNsaWNlIGluZGV4LCBzbGljZSB2' + - 'YWx1ZSkgYXNtKHZhbHVlIGluZGV4IGRpY3Qga2V5X2xlbikgIkRJQ1RTRVQiOwooY2VsbCwgKCkpIH5kaWN0X3NldChjZWxsIGRpY3QsIGludCBrZXlfbGVuLCBzbGlj' + - 'ZSBpbmRleCwgc2xpY2UgdmFsdWUpIGFzbSh2YWx1ZSBpbmRleCBkaWN0IGtleV9sZW4pICJESUNUU0VUIjsKKGNlbGwsIGludCkgdWRpY3RfYWRkPyhjZWxsIGRpY3Qs' + - 'IGludCBrZXlfbGVuLCBpbnQgaW5kZXgsIHNsaWNlIHZhbHVlKSBhc20odmFsdWUgaW5kZXggZGljdCBrZXlfbGVuKSAiRElDVFVBREQiOwooY2VsbCwgaW50KSB1ZGlj' + - 'dF9yZXBsYWNlPyhjZWxsIGRpY3QsIGludCBrZXlfbGVuLCBpbnQgaW5kZXgsIHNsaWNlIHZhbHVlKSBhc20odmFsdWUgaW5kZXggZGljdCBrZXlfbGVuKSAiRElDVFVS' + - 'RVBMQUNFIjsKKGNlbGwsIGludCkgaWRpY3RfYWRkPyhjZWxsIGRpY3QsIGludCBrZXlfbGVuLCBpbnQgaW5kZXgsIHNsaWNlIHZhbHVlKSBhc20odmFsdWUgaW5kZXgg' + - 'ZGljdCBrZXlfbGVuKSAiRElDVElBREQiOwooY2VsbCwgaW50KSBpZGljdF9yZXBsYWNlPyhjZWxsIGRpY3QsIGludCBrZXlfbGVuLCBpbnQgaW5kZXgsIHNsaWNlIHZh' + - 'bHVlKSBhc20odmFsdWUgaW5kZXggZGljdCBrZXlfbGVuKSAiRElDVElSRVBMQUNFIjsKY2VsbCB1ZGljdF9zZXRfYnVpbGRlcihjZWxsIGRpY3QsIGludCBrZXlfbGVu' + - 'LCBpbnQgaW5kZXgsIGJ1aWxkZXIgdmFsdWUpIGFzbSh2YWx1ZSBpbmRleCBkaWN0IGtleV9sZW4pICJESUNUVVNFVEIiOwooY2VsbCwgKCkpIH51ZGljdF9zZXRfYnVp' + - 'bGRlcihjZWxsIGRpY3QsIGludCBrZXlfbGVuLCBpbnQgaW5kZXgsIGJ1aWxkZXIgdmFsdWUpIGFzbSh2YWx1ZSBpbmRleCBkaWN0IGtleV9sZW4pICJESUNUVVNFVEIi' + - 'OwpjZWxsIGlkaWN0X3NldF9idWlsZGVyKGNlbGwgZGljdCwgaW50IGtleV9sZW4sIGludCBpbmRleCwgYnVpbGRlciB2YWx1ZSkgYXNtKHZhbHVlIGluZGV4IGRpY3Qg' + - 'a2V5X2xlbikgIkRJQ1RJU0VUQiI7CihjZWxsLCAoKSkgfmlkaWN0X3NldF9idWlsZGVyKGNlbGwgZGljdCwgaW50IGtleV9sZW4sIGludCBpbmRleCwgYnVpbGRlciB2' + - 'YWx1ZSkgYXNtKHZhbHVlIGluZGV4IGRpY3Qga2V5X2xlbikgIkRJQ1RJU0VUQiI7CmNlbGwgZGljdF9zZXRfYnVpbGRlcihjZWxsIGRpY3QsIGludCBrZXlfbGVuLCBz' + - 'bGljZSBpbmRleCwgYnVpbGRlciB2YWx1ZSkgYXNtKHZhbHVlIGluZGV4IGRpY3Qga2V5X2xlbikgIkRJQ1RTRVRCIjsKKGNlbGwsICgpKSB+ZGljdF9zZXRfYnVpbGRl' + - 'cihjZWxsIGRpY3QsIGludCBrZXlfbGVuLCBzbGljZSBpbmRleCwgYnVpbGRlciB2YWx1ZSkgYXNtKHZhbHVlIGluZGV4IGRpY3Qga2V5X2xlbikgIkRJQ1RTRVRCIjsK' + - 'KGNlbGwsIGludCkgdWRpY3RfYWRkX2J1aWxkZXI/KGNlbGwgZGljdCwgaW50IGtleV9sZW4sIGludCBpbmRleCwgYnVpbGRlciB2YWx1ZSkgYXNtKHZhbHVlIGluZGV4' + - 'IGRpY3Qga2V5X2xlbikgIkRJQ1RVQUREQiI7CihjZWxsLCBpbnQpIHVkaWN0X3JlcGxhY2VfYnVpbGRlcj8oY2VsbCBkaWN0LCBpbnQga2V5X2xlbiwgaW50IGluZGV4' + - 'LCBidWlsZGVyIHZhbHVlKSBhc20odmFsdWUgaW5kZXggZGljdCBrZXlfbGVuKSAiRElDVFVSRVBMQUNFQiI7CihjZWxsLCBpbnQpIGlkaWN0X2FkZF9idWlsZGVyPyhj' + - 'ZWxsIGRpY3QsIGludCBrZXlfbGVuLCBpbnQgaW5kZXgsIGJ1aWxkZXIgdmFsdWUpIGFzbSh2YWx1ZSBpbmRleCBkaWN0IGtleV9sZW4pICJESUNUSUFEREIiOwooY2Vs' + - 'bCwgaW50KSBpZGljdF9yZXBsYWNlX2J1aWxkZXI/KGNlbGwgZGljdCwgaW50IGtleV9sZW4sIGludCBpbmRleCwgYnVpbGRlciB2YWx1ZSkgYXNtKHZhbHVlIGluZGV4' + - 'IGRpY3Qga2V5X2xlbikgIkRJQ1RJUkVQTEFDRUIiOwooY2VsbCwgaW50LCBzbGljZSwgaW50KSB1ZGljdF9kZWxldGVfZ2V0X21pbihjZWxsIGRpY3QsIGludCBrZXlf' + - 'bGVuKSBhc20oLT4gMCAyIDEgMykgIkRJQ1RVUkVNTUlOIiAiTlVMTFNXQVBJRk5PVDIiOwooY2VsbCwgKGludCwgc2xpY2UsIGludCkpIH51ZGljdDo6ZGVsZXRlX2dl' + - 'dF9taW4oY2VsbCBkaWN0LCBpbnQga2V5X2xlbikgYXNtKC0+IDAgMiAxIDMpICJESUNUVVJFTU1JTiIgIk5VTExTV0FQSUZOT1QyIjsKKGNlbGwsIGludCwgc2xpY2Us' + - 'IGludCkgaWRpY3RfZGVsZXRlX2dldF9taW4oY2VsbCBkaWN0LCBpbnQga2V5X2xlbikgYXNtKC0+IDAgMiAxIDMpICJESUNUSVJFTU1JTiIgIk5VTExTV0FQSUZOT1Qy' + - 'IjsKKGNlbGwsIChpbnQsIHNsaWNlLCBpbnQpKSB+aWRpY3Q6OmRlbGV0ZV9nZXRfbWluKGNlbGwgZGljdCwgaW50IGtleV9sZW4pIGFzbSgtPiAwIDIgMSAzKSAiRElD' + - 'VElSRU1NSU4iICJOVUxMU1dBUElGTk9UMiI7CihjZWxsLCBzbGljZSwgc2xpY2UsIGludCkgZGljdF9kZWxldGVfZ2V0X21pbihjZWxsIGRpY3QsIGludCBrZXlfbGVu' + - 'KSBhc20oLT4gMCAyIDEgMykgIkRJQ1RSRU1NSU4iICJOVUxMU1dBUElGTk9UMiI7CihjZWxsLCAoc2xpY2UsIHNsaWNlLCBpbnQpKSB+ZGljdDo6ZGVsZXRlX2dldF9t' + - 'aW4oY2VsbCBkaWN0LCBpbnQga2V5X2xlbikgYXNtKC0+IDAgMiAxIDMpICJESUNUUkVNTUlOIiAiTlVMTFNXQVBJRk5PVDIiOwooY2VsbCwgaW50LCBzbGljZSwgaW50' + - 'KSB1ZGljdF9kZWxldGVfZ2V0X21heChjZWxsIGRpY3QsIGludCBrZXlfbGVuKSBhc20oLT4gMCAyIDEgMykgIkRJQ1RVUkVNTUFYIiAiTlVMTFNXQVBJRk5PVDIiOwoo' + - 'Y2VsbCwgKGludCwgc2xpY2UsIGludCkpIH51ZGljdDo6ZGVsZXRlX2dldF9tYXgoY2VsbCBkaWN0LCBpbnQga2V5X2xlbikgYXNtKC0+IDAgMiAxIDMpICJESUNUVVJF' + - 'TU1BWCIgIk5VTExTV0FQSUZOT1QyIjsKKGNlbGwsIGludCwgc2xpY2UsIGludCkgaWRpY3RfZGVsZXRlX2dldF9tYXgoY2VsbCBkaWN0LCBpbnQga2V5X2xlbikgYXNt' + - 'KC0+IDAgMiAxIDMpICJESUNUSVJFTU1BWCIgIk5VTExTV0FQSUZOT1QyIjsKKGNlbGwsIChpbnQsIHNsaWNlLCBpbnQpKSB+aWRpY3Q6OmRlbGV0ZV9nZXRfbWF4KGNl' + - 'bGwgZGljdCwgaW50IGtleV9sZW4pIGFzbSgtPiAwIDIgMSAzKSAiRElDVElSRU1NQVgiICJOVUxMU1dBUElGTk9UMiI7CihjZWxsLCBzbGljZSwgc2xpY2UsIGludCkg' + - 'ZGljdF9kZWxldGVfZ2V0X21heChjZWxsIGRpY3QsIGludCBrZXlfbGVuKSBhc20oLT4gMCAyIDEgMykgIkRJQ1RSRU1NQVgiICJOVUxMU1dBUElGTk9UMiI7CihjZWxs' + - 'LCAoc2xpY2UsIHNsaWNlLCBpbnQpKSB+ZGljdDo6ZGVsZXRlX2dldF9tYXgoY2VsbCBkaWN0LCBpbnQga2V5X2xlbikgYXNtKC0+IDAgMiAxIDMpICJESUNUUkVNTUFY' + - 'IiAiTlVMTFNXQVBJRk5PVDIiOwooaW50LCBzbGljZSwgaW50KSB1ZGljdF9nZXRfbWluPyhjZWxsIGRpY3QsIGludCBrZXlfbGVuKSBhc20gKC0+IDEgMCAyKSAiRElD' + - 'VFVNSU4iICJOVUxMU1dBUElGTk9UMiI7CihpbnQsIHNsaWNlLCBpbnQpIHVkaWN0X2dldF9tYXg/KGNlbGwgZGljdCwgaW50IGtleV9sZW4pIGFzbSAoLT4gMSAwIDIp' + - 'ICJESUNUVU1BWCIgIk5VTExTV0FQSUZOT1QyIjsKKGludCwgY2VsbCwgaW50KSB1ZGljdF9nZXRfbWluX3JlZj8oY2VsbCBkaWN0LCBpbnQga2V5X2xlbikgYXNtICgt' + - 'PiAxIDAgMikgIkRJQ1RVTUlOUkVGIiAiTlVMTFNXQVBJRk5PVDIiOwooaW50LCBjZWxsLCBpbnQpIHVkaWN0X2dldF9tYXhfcmVmPyhjZWxsIGRpY3QsIGludCBrZXlf' + - 'bGVuKSBhc20gKC0+IDEgMCAyKSAiRElDVFVNQVhSRUYiICJOVUxMU1dBUElGTk9UMiI7CihpbnQsIHNsaWNlLCBpbnQpIGlkaWN0X2dldF9taW4/KGNlbGwgZGljdCwg' + - 'aW50IGtleV9sZW4pIGFzbSAoLT4gMSAwIDIpICJESUNUSU1JTiIgIk5VTExTV0FQSUZOT1QyIjsKKGludCwgc2xpY2UsIGludCkgaWRpY3RfZ2V0X21heD8oY2VsbCBk' + - 'aWN0LCBpbnQga2V5X2xlbikgYXNtICgtPiAxIDAgMikgIkRJQ1RJTUFYIiAiTlVMTFNXQVBJRk5PVDIiOwooaW50LCBjZWxsLCBpbnQpIGlkaWN0X2dldF9taW5fcmVm' + - 'PyhjZWxsIGRpY3QsIGludCBrZXlfbGVuKSBhc20gKC0+IDEgMCAyKSAiRElDVElNSU5SRUYiICJOVUxMU1dBUElGTk9UMiI7CihpbnQsIGNlbGwsIGludCkgaWRpY3Rf' + - 'Z2V0X21heF9yZWY/KGNlbGwgZGljdCwgaW50IGtleV9sZW4pIGFzbSAoLT4gMSAwIDIpICJESUNUSU1BWFJFRiIgIk5VTExTV0FQSUZOT1QyIjsKKGludCwgc2xpY2Us' + - 'IGludCkgdWRpY3RfZ2V0X25leHQ/KGNlbGwgZGljdCwgaW50IGtleV9sZW4sIGludCBwaXZvdCkgYXNtKHBpdm90IGRpY3Qga2V5X2xlbiAtPiAxIDAgMikgIkRJQ1RV' + - 'R0VUTkVYVCIgIk5VTExTV0FQSUZOT1QyIjsKKGludCwgc2xpY2UsIGludCkgdWRpY3RfZ2V0X25leHRlcT8oY2VsbCBkaWN0LCBpbnQga2V5X2xlbiwgaW50IHBpdm90' + - 'KSBhc20ocGl2b3QgZGljdCBrZXlfbGVuIC0+IDEgMCAyKSAiRElDVFVHRVRORVhURVEiICJOVUxMU1dBUElGTk9UMiI7CihpbnQsIHNsaWNlLCBpbnQpIHVkaWN0X2dl' + - 'dF9wcmV2PyhjZWxsIGRpY3QsIGludCBrZXlfbGVuLCBpbnQgcGl2b3QpIGFzbShwaXZvdCBkaWN0IGtleV9sZW4gLT4gMSAwIDIpICJESUNUVUdFVFBSRVYiICJOVUxM' + - 'U1dBUElGTk9UMiI7CihpbnQsIHNsaWNlLCBpbnQpIHVkaWN0X2dldF9wcmV2ZXE/KGNlbGwgZGljdCwgaW50IGtleV9sZW4sIGludCBwaXZvdCkgYXNtKHBpdm90IGRp' + - 'Y3Qga2V5X2xlbiAtPiAxIDAgMikgIkRJQ1RVR0VUUFJFVkVRIiAiTlVMTFNXQVBJRk5PVDIiOwooaW50LCBzbGljZSwgaW50KSBpZGljdF9nZXRfbmV4dD8oY2VsbCBk' + - 'aWN0LCBpbnQga2V5X2xlbiwgaW50IHBpdm90KSBhc20ocGl2b3QgZGljdCBrZXlfbGVuIC0+IDEgMCAyKSAiRElDVElHRVRORVhUIiAiTlVMTFNXQVBJRk5PVDIiOwoo' + - 'aW50LCBzbGljZSwgaW50KSBpZGljdF9nZXRfbmV4dGVxPyhjZWxsIGRpY3QsIGludCBrZXlfbGVuLCBpbnQgcGl2b3QpIGFzbShwaXZvdCBkaWN0IGtleV9sZW4gLT4g' + - 'MSAwIDIpICJESUNUSUdFVE5FWFRFUSIgIk5VTExTV0FQSUZOT1QyIjsKKGludCwgc2xpY2UsIGludCkgaWRpY3RfZ2V0X3ByZXY/KGNlbGwgZGljdCwgaW50IGtleV9s' + - 'ZW4sIGludCBwaXZvdCkgYXNtKHBpdm90IGRpY3Qga2V5X2xlbiAtPiAxIDAgMikgIkRJQ1RJR0VUUFJFViIgIk5VTExTV0FQSUZOT1QyIjsKKGludCwgc2xpY2UsIGlu' + - 'dCkgaWRpY3RfZ2V0X3ByZXZlcT8oY2VsbCBkaWN0LCBpbnQga2V5X2xlbiwgaW50IHBpdm90KSBhc20ocGl2b3QgZGljdCBrZXlfbGVuIC0+IDEgMCAyKSAiRElDVElH' + - 'RVRQUkVWRVEiICJOVUxMU1dBUElGTk9UMiI7Cgo7OzsgQ3JlYXRlcyBhbiBlbXB0eSBkaWN0aW9uYXJ5LCB3aGljaCBpcyBhY3R1YWxseSBhIG51bGwgdmFsdWUuIEVx' + - 'dWl2YWxlbnQgdG8gUFVTSE5VTEwKY2VsbCBuZXdfZGljdCgpIGFzbSAiTkVXRElDVCI7Cjs7OyBDaGVja3Mgd2hldGhlciBhIGRpY3Rpb25hcnkgaXMgZW1wdHkuIEVx' + - 'dWl2YWxlbnQgdG8gY2VsbF9udWxsPy4KaW50IGRpY3RfZW1wdHk/KGNlbGwgYykgYXNtICJESUNURU1QVFkiOwoKCnstIFByZWZpeCBkaWN0aW9uYXJ5IHByaW1pdGl2' + - 'ZXMgLX0KKHNsaWNlLCBzbGljZSwgc2xpY2UsIGludCkgcGZ4ZGljdF9nZXQ/KGNlbGwgZGljdCwgaW50IGtleV9sZW4sIHNsaWNlIGtleSkgYXNtKGtleSBkaWN0IGtl' + - 'eV9sZW4pICJQRlhESUNUR0VUUSIgIk5VTExTV0FQSUZOT1QyIjsKKGNlbGwsIGludCkgcGZ4ZGljdF9zZXQ/KGNlbGwgZGljdCwgaW50IGtleV9sZW4sIHNsaWNlIGtl' + - 'eSwgc2xpY2UgdmFsdWUpIGFzbSh2YWx1ZSBrZXkgZGljdCBrZXlfbGVuKSAiUEZYRElDVFNFVCI7CihjZWxsLCBpbnQpIHBmeGRpY3RfZGVsZXRlPyhjZWxsIGRpY3Qs' + - 'IGludCBrZXlfbGVuLCBzbGljZSBrZXkpIGFzbShrZXkgZGljdCBrZXlfbGVuKSAiUEZYRElDVERFTCI7Cgo7OzsgUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIGdsb2Jh' + - 'bCBjb25maWd1cmF0aW9uIHBhcmFtZXRlciB3aXRoIGludGVnZXIgaW5kZXggYGlgIGFzIGEgYGNlbGxgIG9yIGBudWxsYCB2YWx1ZS4KY2VsbCBjb25maWdfcGFyYW0o' + - 'aW50IHgpIGFzbSAiQ09ORklHT1BUUEFSQU0iOwo7OzsgQ2hlY2tzIHdoZXRoZXIgYyBpcyBhIG51bGwuIE5vdGUsIHRoYXQgRnVuQyBhbHNvIGhhcyBwb2x5bW9ycGhp' + - 'YyBudWxsPyBidWlsdC1pbi4KaW50IGNlbGxfbnVsbD8oY2VsbCBjKSBhc20gIklTTlVMTCI7Cgo7OzsgQ3JlYXRlcyBhbiBvdXRwdXQgYWN0aW9uIHdoaWNoIHdvdWxk' + - 'IHJlc2VydmUgZXhhY3RseSBhbW91bnQgbmFub3RvbmNvaW5zIChpZiBtb2RlID0gMCksIGF0IG1vc3QgYW1vdW50IG5hbm90b25jb2lucyAoaWYgbW9kZSA9IDIpLCBv' + - 'ciBhbGwgYnV0IGFtb3VudCBuYW5vdG9uY29pbnMgKGlmIG1vZGUgPSAxIG9yIG1vZGUgPSAzKSwgZnJvbSB0aGUgcmVtYWluaW5nIGJhbGFuY2Ugb2YgdGhlIGFjY291' + - 'bnQuIEl0IGlzIHJvdWdobHkgZXF1aXZhbGVudCB0byBjcmVhdGluZyBhbiBvdXRib3VuZCBtZXNzYWdlIGNhcnJ5aW5nIGFtb3VudCBuYW5vdG9uY29pbnMgKG9yIGIg' + - '4oiSIGFtb3VudCBuYW5vdG9uY29pbnMsIHdoZXJlIGIgaXMgdGhlIHJlbWFpbmluZyBiYWxhbmNlKSB0byBvbmVzZWxmLCBzbyB0aGF0IHRoZSBzdWJzZXF1ZW50IG91' + - 'dHB1dCBhY3Rpb25zIHdvdWxkIG5vdCBiZSBhYmxlIHRvIHNwZW5kIG1vcmUgbW9uZXkgdGhhbiB0aGUgcmVtYWluZGVyLiBCaXQgKzIgaW4gbW9kZSBtZWFucyB0aGF0' + - 'IHRoZSBleHRlcm5hbCBhY3Rpb24gZG9lcyBub3QgZmFpbCBpZiB0aGUgc3BlY2lmaWVkIGFtb3VudCBjYW5ub3QgYmUgcmVzZXJ2ZWQ7IGluc3RlYWQsIGFsbCByZW1h' + - 'aW5pbmcgYmFsYW5jZSBpcyByZXNlcnZlZC4gQml0ICs4IGluIG1vZGUgbWVhbnMgYGFtb3VudCA8LSAtYW1vdW50YCBiZWZvcmUgcGVyZm9ybWluZyBhbnkgZnVydGhl' + - 'ciBhY3Rpb25zLiBCaXQgKzQgaW4gbW9kZSBtZWFucyB0aGF0IGFtb3VudCBpcyBpbmNyZWFzZWQgYnkgdGhlIG9yaWdpbmFsIGJhbGFuY2Ugb2YgdGhlIGN1cnJlbnQg' + - 'YWNjb3VudCAoYmVmb3JlIHRoZSBjb21wdXRlIHBoYXNlKSwgaW5jbHVkaW5nIGFsbCBleHRyYSBjdXJyZW5jaWVzLCBiZWZvcmUgcGVyZm9ybWluZyBhbnkgb3RoZXIg' + - 'Y2hlY2tzIGFuZCBhY3Rpb25zLiBDdXJyZW50bHksIGFtb3VudCBtdXN0IGJlIGEgbm9uLW5lZ2F0aXZlIGludGVnZXIsIGFuZCBtb2RlIG11c3QgYmUgaW4gdGhlIHJh' + - 'bmdlIDAuLjE1LgooKSByYXdfcmVzZXJ2ZShpbnQgYW1vdW50LCBpbnQgbW9kZSkgaW1wdXJlIGFzbSAiUkFXUkVTRVJWRSI7Cjs7OyBTaW1pbGFyIHRvIHJhd19yZXNl' + - 'cnZlLCBidXQgYWxzbyBhY2NlcHRzIGEgZGljdGlvbmFyeSBleHRyYV9hbW91bnQgKHJlcHJlc2VudGVkIGJ5IGEgY2VsbCBvciBudWxsKSB3aXRoIGV4dHJhIGN1cnJl' + - 'bmNpZXMuIEluIHRoaXMgd2F5IGN1cnJlbmNpZXMgb3RoZXIgdGhhbiBUb25Db2luIGNhbiBiZSByZXNlcnZlZC4KKCkgcmF3X3Jlc2VydmVfZXh0cmEoaW50IGFtb3Vu' + - 'dCwgY2VsbCBleHRyYV9hbW91bnQsIGludCBtb2RlKSBpbXB1cmUgYXNtICJSQVdSRVNFUlZFWCI7Cjs7OyBTZW5kcyBhIHJhdyBtZXNzYWdlIGNvbnRhaW5lZCBpbiBt' + - 'c2csIHdoaWNoIHNob3VsZCBjb250YWluIGEgY29ycmVjdGx5IHNlcmlhbGl6ZWQgb2JqZWN0IE1lc3NhZ2UgWCwgd2l0aCB0aGUgb25seSBleGNlcHRpb24gdGhhdCB0' + - 'aGUgc291cmNlIGFkZHJlc3MgaXMgYWxsb3dlZCB0byBoYXZlIGR1bW15IHZhbHVlIGFkZHJfbm9uZSAodG8gYmUgYXV0b21hdGljYWxseSByZXBsYWNlZCB3aXRoIHRo' + - 'ZSBjdXJyZW50IHNtYXJ0IGNvbnRyYWN0IGFkZHJlc3MpLCBhbmQgaWhyX2ZlZSwgZndkX2ZlZSwgY3JlYXRlZF9sdCBhbmQgY3JlYXRlZF9hdCBmaWVsZHMgY2FuIGhh' + - 'dmUgYXJiaXRyYXJ5IHZhbHVlcyAodG8gYmUgcmV3cml0dGVuIHdpdGggY29ycmVjdCB2YWx1ZXMgZHVyaW5nIHRoZSBhY3Rpb24gcGhhc2Ugb2YgdGhlIGN1cnJlbnQg' + - 'dHJhbnNhY3Rpb24pLiBJbnRlZ2VyIHBhcmFtZXRlciBtb2RlIGNvbnRhaW5zIHRoZSBmbGFncy4gQ3VycmVudGx5IG1vZGUgPSAwIGlzIHVzZWQgZm9yIG9yZGluYXJ5' + - 'IG1lc3NhZ2VzOyBtb2RlID0gMTI4IGlzIHVzZWQgZm9yIG1lc3NhZ2VzIHRoYXQgYXJlIHRvIGNhcnJ5IGFsbCB0aGUgcmVtYWluaW5nIGJhbGFuY2Ugb2YgdGhlIGN1' + - 'cnJlbnQgc21hcnQgY29udHJhY3QgKGluc3RlYWQgb2YgdGhlIHZhbHVlIG9yaWdpbmFsbHkgaW5kaWNhdGVkIGluIHRoZSBtZXNzYWdlKTsgbW9kZSA9IDY0IGlzIHVz' + - 'ZWQgZm9yIG1lc3NhZ2VzIHRoYXQgY2FycnkgYWxsIHRoZSByZW1haW5pbmcgdmFsdWUgb2YgdGhlIGluYm91bmQgbWVzc2FnZSBpbiBhZGRpdGlvbiB0byB0aGUgdmFs' + - 'dWUgaW5pdGlhbGx5IGluZGljYXRlZCBpbiB0aGUgbmV3IG1lc3NhZ2UgKGlmIGJpdCAwIGlzIG5vdCBzZXQsIHRoZSBnYXMgZmVlcyBhcmUgZGVkdWN0ZWQgZnJvbSB0' + - 'aGlzIGFtb3VudCk7IG1vZGUnID0gbW9kZSArIDEgbWVhbnMgdGhhdCB0aGUgc2VuZGVyIHdhbnRzIHRvIHBheSB0cmFuc2ZlciBmZWVzIHNlcGFyYXRlbHk7IG1vZGUn' + - 'ID0gbW9kZSArIDIgbWVhbnMgdGhhdCBhbnkgZXJyb3JzIGFyaXNpbmcgd2hpbGUgcHJvY2Vzc2luZyB0aGlzIG1lc3NhZ2UgZHVyaW5nIHRoZSBhY3Rpb24gcGhhc2Ug' + - 'c2hvdWxkIGJlIGlnbm9yZWQuIEZpbmFsbHksIG1vZGUnID0gbW9kZSArIDMyIG1lYW5zIHRoYXQgdGhlIGN1cnJlbnQgYWNjb3VudCBtdXN0IGJlIGRlc3Ryb3llZCBp' + - 'ZiBpdHMgcmVzdWx0aW5nIGJhbGFuY2UgaXMgemVyby4gVGhpcyBmbGFnIGlzIHVzdWFsbHkgZW1wbG95ZWQgdG9nZXRoZXIgd2l0aCArMTI4LgooKSBzZW5kX3Jhd19t' + - 'ZXNzYWdlKGNlbGwgbXNnLCBpbnQgbW9kZSkgaW1wdXJlIGFzbSAiU0VORFJBV01TRyI7Cjs7OyBDcmVhdGVzIGFuIG91dHB1dCBhY3Rpb24gdGhhdCB3b3VsZCBjaGFu' + - 'Z2UgdGhpcyBzbWFydCBjb250cmFjdCBjb2RlIHRvIHRoYXQgZ2l2ZW4gYnkgY2VsbCBuZXdfY29kZS4gTm90aWNlIHRoYXQgdGhpcyBjaGFuZ2Ugd2lsbCB0YWtlIGVm' + - 'ZmVjdCBvbmx5IGFmdGVyIHRoZSBzdWNjZXNzZnVsIHRlcm1pbmF0aW9uIG9mIHRoZSBjdXJyZW50IHJ1biBvZiB0aGUgc21hcnQgY29udHJhY3QKKCkgc2V0X2NvZGUo' + - 'Y2VsbCBuZXdfY29kZSkgaW1wdXJlIGFzbSAiU0VUQ09ERSI7Cgo7OzsgR2VuZXJhdGVzIGEgbmV3IHBzZXVkby1yYW5kb20gdW5zaWduZWQgMjU2LWJpdCBpbnRlZ2Vy' + - 'IHguIFRoZSBhbGdvcml0aG0gaXMgYXMgZm9sbG93czogaWYgciBpcyB0aGUgb2xkIHZhbHVlIG9mIHRoZSByYW5kb20gc2VlZCwgY29uc2lkZXJlZCBhcyBhIDMyLWJ5' + - 'dGUgYXJyYXkgKGJ5IGNvbnN0cnVjdGluZyB0aGUgYmlnLWVuZGlhbiByZXByZXNlbnRhdGlvbiBvZiBhbiB1bnNpZ25lZCAyNTYtYml0IGludGVnZXIpLCB0aGVuIGl0' + - 'cyBzaGE1MTIocikgaXMgY29tcHV0ZWQ7IHRoZSBmaXJzdCAzMiBieXRlcyBvZiB0aGlzIGhhc2ggYXJlIHN0b3JlZCBhcyB0aGUgbmV3IHZhbHVlIHInIG9mIHRoZSBy' + - 'YW5kb20gc2VlZCwgYW5kIHRoZSByZW1haW5pbmcgMzIgYnl0ZXMgYXJlIHJldHVybmVkIGFzIHRoZSBuZXh0IHJhbmRvbSB2YWx1ZSB4LgppbnQgcmFuZG9tKCkgaW1w' + - 'dXJlIGFzbSAiUkFORFUyNTYiOwo7OzsgR2VuZXJhdGVzIGEgbmV3IHBzZXVkby1yYW5kb20gaW50ZWdlciB6IGluIHRoZSByYW5nZSAwLi5yYW5nZeKIkjEgKG9yIHJh' + - 'bmdlLi7iiJIxLCBpZiByYW5nZSA8IDApLiBNb3JlIHByZWNpc2VseSwgYW4gdW5zaWduZWQgcmFuZG9tIHZhbHVlIHggaXMgZ2VuZXJhdGVkIGFzIGluIHJhbmRvbTsg' + - 'dGhlbiB6IDo9IHggKiByYW5nZSAvIDJeMjU2IGlzIGNvbXB1dGVkLgppbnQgcmFuZChpbnQgcmFuZ2UpIGltcHVyZSBhc20gIlJBTkQiOwo7OzsgUmV0dXJucyB0aGUg' + - 'Y3VycmVudCByYW5kb20gc2VlZCBhcyBhbiB1bnNpZ25lZCAyNTYtYml0IEludGVnZXIuCmludCBnZXRfc2VlZCgpIGltcHVyZSBhc20gIlJBTkRTRUVEIjsKOzs7IFNl' + - 'dHMgdGhlIHJhbmRvbSBzZWVkIHRvIHVuc2lnbmVkIDI1Ni1iaXQgc2VlZC4KKCkgc2V0X3NlZWQoaW50IHgpIGltcHVyZSBhc20gIlNFVFJBTkQiOwo7OzsgTWl4ZXMg' + - 'dW5zaWduZWQgMjU2LWJpdCBpbnRlZ2VyIHggaW50byB0aGUgcmFuZG9tIHNlZWQgciBieSBzZXR0aW5nIHRoZSByYW5kb20gc2VlZCB0byBzaGEyNTYgb2YgdGhlIGNv' + - 'bmNhdGVuYXRpb24gb2YgdHdvIDMyLWJ5dGUgc3RyaW5nczogdGhlIGZpcnN0IHdpdGggdGhlIGJpZy1lbmRpYW4gcmVwcmVzZW50YXRpb24gb2YgdGhlIG9sZCBzZWVk' + - 'IHIsIGFuZCB0aGUgc2Vjb25kIHdpdGggdGhlIGJpZy1lbmRpYW4gcmVwcmVzZW50YXRpb24gb2YgeC4KKCkgcmFuZG9taXplKGludCB4KSBpbXB1cmUgYXNtICJBRERS' + - 'QU5EIjsKOzs7IEVxdWl2YWxlbnQgdG8gcmFuZG9taXplKGN1cl9sdCgpKTsuCigpIHJhbmRvbWl6ZV9sdCgpIGltcHVyZSBhc20gIkxUSU1FIiAiQUREUkFORCI7Cgo7' + - 'OzsgQ2hlY2tzIHdoZXRoZXIgdGhlIGRhdGEgcGFydHMgb2YgdHdvIHNsaWNlcyBjb2luc2lkZQppbnQgZXF1YWxfc2xpY2VzX2JpdHMoc2xpY2UgYSwgc2xpY2UgYikg' + - 'YXNtICJTREVRIjsKOzs7IENoZWNrcyB3aGV0aGVyIGIgaXMgYSBudWxsLiBOb3RlLCB0aGF0IEZ1bkMgYWxzbyBoYXMgcG9seW1vcnBoaWMgbnVsbD8gYnVpbHQtaW4u' + - 'CmludCBidWlsZGVyX251bGw/KGJ1aWxkZXIgYikgYXNtICJJU05VTEwiOwo7OzsgQ29uY2F0ZW5hdGVzIHR3byBidWlsZGVycwpidWlsZGVyIHN0b3JlX2J1aWxkZXIo' + - 'YnVpbGRlciB0bywgYnVpbGRlciBmcm9tKSBhc20gIlNUQlIiOwoKOzsgQ1VTVE9NOgoKOzsgVFZNIFVQR1JBREUgMjAyMy0wNyBodHRwczovL2RvY3MudG9uLm9yZy9s' + - 'ZWFybi90dm0taW5zdHJ1Y3Rpb25zL3R2bS11cGdyYWRlLTIwMjMtMDcKOzsgSW4gbWFpbm5ldCBzaW5jZSAyMCBEZWMgMjAyMyBodHRwczovL3QubWUvdG9uYmxvY2tj' + - 'aGFpbi8yMjYKCjs7OyBSZXRyaWV2ZXMgY29kZSBvZiBzbWFydC1jb250cmFjdCBmcm9tIGM3CmNlbGwgbXlfY29kZSgpIGFzbSAiTVlDT0RFIjsK'; + 'aWN0LCBpbnQga2V5X2xlbiwgaW50IGluZGV4KSBhc20oaW5kZXggZGljdCBrZXlfbGVuKSAiRElDVFVERUxHRVQiICJOVUxMU1dBUElGTk9UIjsKKGNlbGwsIGNlbGws' + + 'IGludCkgaWRpY3RfZGVsZXRlX2dldF9yZWY/KGNlbGwgZGljdCwgaW50IGtleV9sZW4sIGludCBpbmRleCkgYXNtKGluZGV4IGRpY3Qga2V5X2xlbikgIkRJQ1RJREVM' + + 'R0VUUkVGIiAiTlVMTFNXQVBJRk5PVCI7CihjZWxsLCBjZWxsLCBpbnQpIHVkaWN0X2RlbGV0ZV9nZXRfcmVmPyhjZWxsIGRpY3QsIGludCBrZXlfbGVuLCBpbnQgaW5k' + + 'ZXgpIGFzbShpbmRleCBkaWN0IGtleV9sZW4pICJESUNUVURFTEdFVFJFRiIgIk5VTExTV0FQSUZOT1QiOwooY2VsbCwgKGNlbGwsIGludCkpIH5pZGljdF9kZWxldGVf' + + 'Z2V0X3JlZj8oY2VsbCBkaWN0LCBpbnQga2V5X2xlbiwgaW50IGluZGV4KSBhc20oaW5kZXggZGljdCBrZXlfbGVuKSAiRElDVElERUxHRVRSRUYiICJOVUxMU1dBUElG' + + 'Tk9UIjsKKGNlbGwsIChjZWxsLCBpbnQpKSB+dWRpY3RfZGVsZXRlX2dldF9yZWY/KGNlbGwgZGljdCwgaW50IGtleV9sZW4sIGludCBpbmRleCkgYXNtKGluZGV4IGRp' + + 'Y3Qga2V5X2xlbikgIkRJQ1RVREVMR0VUUkVGIiAiTlVMTFNXQVBJRk5PVCI7CmNlbGwgdWRpY3Rfc2V0KGNlbGwgZGljdCwgaW50IGtleV9sZW4sIGludCBpbmRleCwg' + + 'c2xpY2UgdmFsdWUpIGFzbSh2YWx1ZSBpbmRleCBkaWN0IGtleV9sZW4pICJESUNUVVNFVCI7CihjZWxsLCAoKSkgfnVkaWN0X3NldChjZWxsIGRpY3QsIGludCBrZXlf' + + 'bGVuLCBpbnQgaW5kZXgsIHNsaWNlIHZhbHVlKSBhc20odmFsdWUgaW5kZXggZGljdCBrZXlfbGVuKSAiRElDVFVTRVQiOwpjZWxsIGlkaWN0X3NldChjZWxsIGRpY3Qs' + + 'IGludCBrZXlfbGVuLCBpbnQgaW5kZXgsIHNsaWNlIHZhbHVlKSBhc20odmFsdWUgaW5kZXggZGljdCBrZXlfbGVuKSAiRElDVElTRVQiOwooY2VsbCwgKCkpIH5pZGlj' + + 'dF9zZXQoY2VsbCBkaWN0LCBpbnQga2V5X2xlbiwgaW50IGluZGV4LCBzbGljZSB2YWx1ZSkgYXNtKHZhbHVlIGluZGV4IGRpY3Qga2V5X2xlbikgIkRJQ1RJU0VUIjsK' + + 'Y2VsbCBkaWN0X3NldChjZWxsIGRpY3QsIGludCBrZXlfbGVuLCBzbGljZSBpbmRleCwgc2xpY2UgdmFsdWUpIGFzbSh2YWx1ZSBpbmRleCBkaWN0IGtleV9sZW4pICJE' + + 'SUNUU0VUIjsKKGNlbGwsICgpKSB+ZGljdF9zZXQoY2VsbCBkaWN0LCBpbnQga2V5X2xlbiwgc2xpY2UgaW5kZXgsIHNsaWNlIHZhbHVlKSBhc20odmFsdWUgaW5kZXgg' + + 'ZGljdCBrZXlfbGVuKSAiRElDVFNFVCI7CihjZWxsLCBpbnQpIHVkaWN0X2FkZD8oY2VsbCBkaWN0LCBpbnQga2V5X2xlbiwgaW50IGluZGV4LCBzbGljZSB2YWx1ZSkg' + + 'YXNtKHZhbHVlIGluZGV4IGRpY3Qga2V5X2xlbikgIkRJQ1RVQUREIjsKKGNlbGwsIGludCkgdWRpY3RfcmVwbGFjZT8oY2VsbCBkaWN0LCBpbnQga2V5X2xlbiwgaW50' + + 'IGluZGV4LCBzbGljZSB2YWx1ZSkgYXNtKHZhbHVlIGluZGV4IGRpY3Qga2V5X2xlbikgIkRJQ1RVUkVQTEFDRSI7CihjZWxsLCBpbnQpIHVkaWN0X3JlcGxhY2VfcmVm' + + 'PyhjZWxsIGRpY3QsIGludCBrZXlfbGVuLCBpbnQgaW5kZXgsIGNlbGwgdmFsdWUpIGFzbSh2YWx1ZSBpbmRleCBkaWN0IGtleV9sZW4pICJESUNUVVJFUExBQ0VSRUYi' + + 'OwooY2VsbCwgc2xpY2UsIGludCkgdWRpY3RfcmVwbGFjZWdldD8oY2VsbCBkaWN0LCBpbnQga2V5X2xlbiwgaW50IGluZGV4LCBzbGljZSB2YWx1ZSkgYXNtKHZhbHVl' + + 'IGluZGV4IGRpY3Qga2V5X2xlbikgIkRJQ1RVUkVQTEFDRUdFVCIgIk5VTExTV0FQSUZOT1QiOwooY2VsbCwgY2VsbCwgaW50KSB1ZGljdF9yZXBsYWNlZ2V0X3JlZj8o' + + 'Y2VsbCBkaWN0LCBpbnQga2V5X2xlbiwgaW50IGluZGV4LCBjZWxsIHZhbHVlKSBhc20odmFsdWUgaW5kZXggZGljdCBrZXlfbGVuKSAiRElDVFVSRVBMQUNFR0VUUkVG' + + 'IiAiTlVMTFNXQVBJRk5PVCI7CihjZWxsLCAoc2xpY2UsIGludCkpIH51ZGljdF9yZXBsYWNlZ2V0PyhjZWxsIGRpY3QsIGludCBrZXlfbGVuLCBpbnQgaW5kZXgsIHNs' + + 'aWNlIHZhbHVlKSBhc20odmFsdWUgaW5kZXggZGljdCBrZXlfbGVuKSAiRElDVFVSRVBMQUNFR0VUIiAiTlVMTFNXQVBJRk5PVCI7CihjZWxsLCAoY2VsbCwgaW50KSkg' + + 'fnVkaWN0X3JlcGxhY2VnZXRfcmVmPyhjZWxsIGRpY3QsIGludCBrZXlfbGVuLCBpbnQgaW5kZXgsIGNlbGwgdmFsdWUpIGFzbSh2YWx1ZSBpbmRleCBkaWN0IGtleV9s' + + 'ZW4pICJESUNUVVJFUExBQ0VHRVRSRUYiICJOVUxMU1dBUElGTk9UIjsKKGNlbGwsIGludCkgaWRpY3RfYWRkPyhjZWxsIGRpY3QsIGludCBrZXlfbGVuLCBpbnQgaW5k' + + 'ZXgsIHNsaWNlIHZhbHVlKSBhc20odmFsdWUgaW5kZXggZGljdCBrZXlfbGVuKSAiRElDVElBREQiOwooY2VsbCwgaW50KSBpZGljdF9yZXBsYWNlPyhjZWxsIGRpY3Qs' + + 'IGludCBrZXlfbGVuLCBpbnQgaW5kZXgsIHNsaWNlIHZhbHVlKSBhc20odmFsdWUgaW5kZXggZGljdCBrZXlfbGVuKSAiRElDVElSRVBMQUNFIjsKKGNlbGwsIGludCkg' + + 'aWRpY3RfcmVwbGFjZV9yZWY/KGNlbGwgZGljdCwgaW50IGtleV9sZW4sIGludCBpbmRleCwgY2VsbCB2YWx1ZSkgYXNtKHZhbHVlIGluZGV4IGRpY3Qga2V5X2xlbikg' + + 'IkRJQ1RJUkVQTEFDRVJFRiI7CihjZWxsLCBzbGljZSwgaW50KSBpZGljdF9yZXBsYWNlZ2V0PyhjZWxsIGRpY3QsIGludCBrZXlfbGVuLCBpbnQgaW5kZXgsIHNsaWNl' + + 'IHZhbHVlKSBhc20odmFsdWUgaW5kZXggZGljdCBrZXlfbGVuKSAiRElDVElSRVBMQUNFR0VUIiAiTlVMTFNXQVBJRk5PVCI7CihjZWxsLCBjZWxsLCBpbnQpIGlkaWN0' + + 'X3JlcGxhY2VnZXRfcmVmPyhjZWxsIGRpY3QsIGludCBrZXlfbGVuLCBpbnQgaW5kZXgsIGNlbGwgdmFsdWUpIGFzbSh2YWx1ZSBpbmRleCBkaWN0IGtleV9sZW4pICJE' + + 'SUNUSVJFUExBQ0VHRVRSRUYiICJOVUxMU1dBUElGTk9UIjsKKGNlbGwsIChzbGljZSwgaW50KSkgfmlkaWN0X3JlcGxhY2VnZXQ/KGNlbGwgZGljdCwgaW50IGtleV9s' + + 'ZW4sIGludCBpbmRleCwgc2xpY2UgdmFsdWUpIGFzbSh2YWx1ZSBpbmRleCBkaWN0IGtleV9sZW4pICJESUNUSVJFUExBQ0VHRVQiICJOVUxMU1dBUElGTk9UIjsKKGNl' + + 'bGwsIChjZWxsLCBpbnQpKSB+aWRpY3RfcmVwbGFjZWdldF9yZWY/KGNlbGwgZGljdCwgaW50IGtleV9sZW4sIGludCBpbmRleCwgY2VsbCB2YWx1ZSkgYXNtKHZhbHVl' + + 'IGluZGV4IGRpY3Qga2V5X2xlbikgIkRJQ1RJUkVQTEFDRUdFVFJFRiIgIk5VTExTV0FQSUZOT1QiOwpjZWxsIHVkaWN0X3NldF9idWlsZGVyKGNlbGwgZGljdCwgaW50' + + 'IGtleV9sZW4sIGludCBpbmRleCwgYnVpbGRlciB2YWx1ZSkgYXNtKHZhbHVlIGluZGV4IGRpY3Qga2V5X2xlbikgIkRJQ1RVU0VUQiI7CihjZWxsLCAoKSkgfnVkaWN0' + + 'X3NldF9idWlsZGVyKGNlbGwgZGljdCwgaW50IGtleV9sZW4sIGludCBpbmRleCwgYnVpbGRlciB2YWx1ZSkgYXNtKHZhbHVlIGluZGV4IGRpY3Qga2V5X2xlbikgIkRJ' + + 'Q1RVU0VUQiI7CmNlbGwgaWRpY3Rfc2V0X2J1aWxkZXIoY2VsbCBkaWN0LCBpbnQga2V5X2xlbiwgaW50IGluZGV4LCBidWlsZGVyIHZhbHVlKSBhc20odmFsdWUgaW5k' + + 'ZXggZGljdCBrZXlfbGVuKSAiRElDVElTRVRCIjsKKGNlbGwsICgpKSB+aWRpY3Rfc2V0X2J1aWxkZXIoY2VsbCBkaWN0LCBpbnQga2V5X2xlbiwgaW50IGluZGV4LCBi' + + 'dWlsZGVyIHZhbHVlKSBhc20odmFsdWUgaW5kZXggZGljdCBrZXlfbGVuKSAiRElDVElTRVRCIjsKY2VsbCBkaWN0X3NldF9idWlsZGVyKGNlbGwgZGljdCwgaW50IGtl' + + 'eV9sZW4sIHNsaWNlIGluZGV4LCBidWlsZGVyIHZhbHVlKSBhc20odmFsdWUgaW5kZXggZGljdCBrZXlfbGVuKSAiRElDVFNFVEIiOwooY2VsbCwgKCkpIH5kaWN0X3Nl' + + 'dF9idWlsZGVyKGNlbGwgZGljdCwgaW50IGtleV9sZW4sIHNsaWNlIGluZGV4LCBidWlsZGVyIHZhbHVlKSBhc20odmFsdWUgaW5kZXggZGljdCBrZXlfbGVuKSAiRElD' + + 'VFNFVEIiOwooY2VsbCwgaW50KSBkaWN0X3JlcGxhY2VfYnVpbGRlcj8oY2VsbCBkaWN0LCBpbnQga2V5X2xlbiwgc2xpY2UgaW5kZXgsIGJ1aWxkZXIgdmFsdWUpIGFz' + + 'bSh2YWx1ZSBpbmRleCBkaWN0IGtleV9sZW4pICJESUNUUkVQTEFDRUIiOwooY2VsbCwgYnVpbGRlciwgaW50KSBkaWN0X3JlcGxhY2VnZXRfYnVpbGRlcj8oY2VsbCBk' + + 'aWN0LCBpbnQga2V5X2xlbiwgc2xpY2UgaW5kZXgsIGJ1aWxkZXIgdmFsdWUpIGFzbSh2YWx1ZSBpbmRleCBkaWN0IGtleV9sZW4pICJESUNUUkVQTEFDRUdFVEIiICJO' + + 'VUxMU1dBUElGTk9UIjsKKGNlbGwsIHNsaWNlLCBpbnQpIGRpY3RfcmVwbGFjZWdldD8oY2VsbCBkaWN0LCBpbnQga2V5X2xlbiwgc2xpY2UgaW5kZXgsIHNsaWNlIHZh' + + 'bHVlKSBhc20odmFsdWUgaW5kZXggZGljdCBrZXlfbGVuKSAiRElDVFJFUExBQ0VHRVQiICJOVUxMU1dBUElGTk9UIjsKKGNlbGwsIChidWlsZGVyLCBpbnQpKSB+ZGlj' + + 'dF9yZXBsYWNlZ2V0X2J1aWxkZXI/KGNlbGwgZGljdCwgaW50IGtleV9sZW4sIHNsaWNlIGluZGV4LCBidWlsZGVyIHZhbHVlKSBhc20odmFsdWUgaW5kZXggZGljdCBr' + + 'ZXlfbGVuKSAiRElDVFJFUExBQ0VHRVRCIiAiTlVMTFNXQVBJRk5PVCI7CihjZWxsLCAoc2xpY2UsIGludCkpIH5kaWN0X3JlcGxhY2VnZXQ/KGNlbGwgZGljdCwgaW50' + + 'IGtleV9sZW4sIHNsaWNlIGluZGV4LCBzbGljZSB2YWx1ZSkgYXNtKHZhbHVlIGluZGV4IGRpY3Qga2V5X2xlbikgIkRJQ1RSRVBMQUNFR0VUIiAiTlVMTFNXQVBJRk5P' + + 'VCI7CihjZWxsLCBpbnQpIHVkaWN0X2FkZF9idWlsZGVyPyhjZWxsIGRpY3QsIGludCBrZXlfbGVuLCBpbnQgaW5kZXgsIGJ1aWxkZXIgdmFsdWUpIGFzbSh2YWx1ZSBp' + + 'bmRleCBkaWN0IGtleV9sZW4pICJESUNUVUFEREIiOwooY2VsbCwgaW50KSB1ZGljdF9yZXBsYWNlX2J1aWxkZXI/KGNlbGwgZGljdCwgaW50IGtleV9sZW4sIGludCBp' + + 'bmRleCwgYnVpbGRlciB2YWx1ZSkgYXNtKHZhbHVlIGluZGV4IGRpY3Qga2V5X2xlbikgIkRJQ1RVUkVQTEFDRUIiOwooY2VsbCwgYnVpbGRlciwgaW50KSB1ZGljdF9y' + + 'ZXBsYWNlZ2V0X2J1aWxkZXI/KGNlbGwgZGljdCwgaW50IGtleV9sZW4sIGludCBpbmRleCwgYnVpbGRlciB2YWx1ZSkgYXNtKHZhbHVlIGluZGV4IGRpY3Qga2V5X2xl' + + 'bikgIkRJQ1RVUkVQTEFDRUdFVEIiICJOVUxMU1dBUElGTk9UIjsKKGNlbGwsIChidWlsZGVyLCBpbnQpKSB+dWRpY3RfcmVwbGFjZWdldF9idWlsZGVyPyhjZWxsIGRp' + + 'Y3QsIGludCBrZXlfbGVuLCBpbnQgaW5kZXgsIGJ1aWxkZXIgdmFsdWUpIGFzbSh2YWx1ZSBpbmRleCBkaWN0IGtleV9sZW4pICJESUNUVVJFUExBQ0VHRVRCIiAiTlVM' + + 'TFNXQVBJRk5PVCI7CihjZWxsLCBpbnQpIGlkaWN0X2FkZF9idWlsZGVyPyhjZWxsIGRpY3QsIGludCBrZXlfbGVuLCBpbnQgaW5kZXgsIGJ1aWxkZXIgdmFsdWUpIGFz' + + 'bSh2YWx1ZSBpbmRleCBkaWN0IGtleV9sZW4pICJESUNUSUFEREIiOwooY2VsbCwgaW50KSBpZGljdF9yZXBsYWNlX2J1aWxkZXI/KGNlbGwgZGljdCwgaW50IGtleV9s' + + 'ZW4sIGludCBpbmRleCwgYnVpbGRlciB2YWx1ZSkgYXNtKHZhbHVlIGluZGV4IGRpY3Qga2V5X2xlbikgIkRJQ1RJUkVQTEFDRUIiOwooY2VsbCwgYnVpbGRlciwgaW50' + + 'KSBpZGljdF9yZXBsYWNlZ2V0X2J1aWxkZXI/KGNlbGwgZGljdCwgaW50IGtleV9sZW4sIGludCBpbmRleCwgYnVpbGRlciB2YWx1ZSkgYXNtKHZhbHVlIGluZGV4IGRp' + + 'Y3Qga2V5X2xlbikgIkRJQ1RJUkVQTEFDRUdFVEIiICJOVUxMU1dBUElGTk9UIjsKKGNlbGwsIChidWlsZGVyLCBpbnQpKSB+aWRpY3RfcmVwbGFjZWdldF9idWlsZGVy' + + 'PyhjZWxsIGRpY3QsIGludCBrZXlfbGVuLCBpbnQgaW5kZXgsIGJ1aWxkZXIgdmFsdWUpIGFzbSh2YWx1ZSBpbmRleCBkaWN0IGtleV9sZW4pICJESUNUSVJFUExBQ0VH' + + 'RVRCIiAiTlVMTFNXQVBJRk5PVCI7CihjZWxsLCBpbnQsIHNsaWNlLCBpbnQpIHVkaWN0X2RlbGV0ZV9nZXRfbWluKGNlbGwgZGljdCwgaW50IGtleV9sZW4pIGFzbSgt' + + 'PiAwIDIgMSAzKSAiRElDVFVSRU1NSU4iICJOVUxMU1dBUElGTk9UMiI7CihjZWxsLCAoaW50LCBzbGljZSwgaW50KSkgfnVkaWN0OjpkZWxldGVfZ2V0X21pbihjZWxs' + + 'IGRpY3QsIGludCBrZXlfbGVuKSBhc20oLT4gMCAyIDEgMykgIkRJQ1RVUkVNTUlOIiAiTlVMTFNXQVBJRk5PVDIiOwooY2VsbCwgaW50LCBzbGljZSwgaW50KSBpZGlj' + + 'dF9kZWxldGVfZ2V0X21pbihjZWxsIGRpY3QsIGludCBrZXlfbGVuKSBhc20oLT4gMCAyIDEgMykgIkRJQ1RJUkVNTUlOIiAiTlVMTFNXQVBJRk5PVDIiOwooY2VsbCwg' + + 'KGludCwgc2xpY2UsIGludCkpIH5pZGljdDo6ZGVsZXRlX2dldF9taW4oY2VsbCBkaWN0LCBpbnQga2V5X2xlbikgYXNtKC0+IDAgMiAxIDMpICJESUNUSVJFTU1JTiIg' + + 'Ik5VTExTV0FQSUZOT1QyIjsKKGNlbGwsIHNsaWNlLCBzbGljZSwgaW50KSBkaWN0X2RlbGV0ZV9nZXRfbWluKGNlbGwgZGljdCwgaW50IGtleV9sZW4pIGFzbSgtPiAw' + + 'IDIgMSAzKSAiRElDVFJFTU1JTiIgIk5VTExTV0FQSUZOT1QyIjsKKGNlbGwsIChzbGljZSwgc2xpY2UsIGludCkpIH5kaWN0OjpkZWxldGVfZ2V0X21pbihjZWxsIGRp' + + 'Y3QsIGludCBrZXlfbGVuKSBhc20oLT4gMCAyIDEgMykgIkRJQ1RSRU1NSU4iICJOVUxMU1dBUElGTk9UMiI7CihjZWxsLCBpbnQsIHNsaWNlLCBpbnQpIHVkaWN0X2Rl' + + 'bGV0ZV9nZXRfbWF4KGNlbGwgZGljdCwgaW50IGtleV9sZW4pIGFzbSgtPiAwIDIgMSAzKSAiRElDVFVSRU1NQVgiICJOVUxMU1dBUElGTk9UMiI7CihjZWxsLCAoaW50' + + 'LCBzbGljZSwgaW50KSkgfnVkaWN0OjpkZWxldGVfZ2V0X21heChjZWxsIGRpY3QsIGludCBrZXlfbGVuKSBhc20oLT4gMCAyIDEgMykgIkRJQ1RVUkVNTUFYIiAiTlVM' + + 'TFNXQVBJRk5PVDIiOwooY2VsbCwgaW50LCBzbGljZSwgaW50KSBpZGljdF9kZWxldGVfZ2V0X21heChjZWxsIGRpY3QsIGludCBrZXlfbGVuKSBhc20oLT4gMCAyIDEg' + + 'MykgIkRJQ1RJUkVNTUFYIiAiTlVMTFNXQVBJRk5PVDIiOwooY2VsbCwgKGludCwgc2xpY2UsIGludCkpIH5pZGljdDo6ZGVsZXRlX2dldF9tYXgoY2VsbCBkaWN0LCBp' + + 'bnQga2V5X2xlbikgYXNtKC0+IDAgMiAxIDMpICJESUNUSVJFTU1BWCIgIk5VTExTV0FQSUZOT1QyIjsKKGNlbGwsIHNsaWNlLCBzbGljZSwgaW50KSBkaWN0X2RlbGV0' + + 'ZV9nZXRfbWF4KGNlbGwgZGljdCwgaW50IGtleV9sZW4pIGFzbSgtPiAwIDIgMSAzKSAiRElDVFJFTU1BWCIgIk5VTExTV0FQSUZOT1QyIjsKKGNlbGwsIChzbGljZSwg' + + 'c2xpY2UsIGludCkpIH5kaWN0OjpkZWxldGVfZ2V0X21heChjZWxsIGRpY3QsIGludCBrZXlfbGVuKSBhc20oLT4gMCAyIDEgMykgIkRJQ1RSRU1NQVgiICJOVUxMU1dB' + + 'UElGTk9UMiI7CihpbnQsIHNsaWNlLCBpbnQpIHVkaWN0X2dldF9taW4/KGNlbGwgZGljdCwgaW50IGtleV9sZW4pIGFzbSAoLT4gMSAwIDIpICJESUNUVU1JTiIgIk5V' + + 'TExTV0FQSUZOT1QyIjsKKGludCwgc2xpY2UsIGludCkgdWRpY3RfZ2V0X21heD8oY2VsbCBkaWN0LCBpbnQga2V5X2xlbikgYXNtICgtPiAxIDAgMikgIkRJQ1RVTUFY' + + 'IiAiTlVMTFNXQVBJRk5PVDIiOwooaW50LCBjZWxsLCBpbnQpIHVkaWN0X2dldF9taW5fcmVmPyhjZWxsIGRpY3QsIGludCBrZXlfbGVuKSBhc20gKC0+IDEgMCAyKSAi' + + 'RElDVFVNSU5SRUYiICJOVUxMU1dBUElGTk9UMiI7CihpbnQsIGNlbGwsIGludCkgdWRpY3RfZ2V0X21heF9yZWY/KGNlbGwgZGljdCwgaW50IGtleV9sZW4pIGFzbSAo' + + 'LT4gMSAwIDIpICJESUNUVU1BWFJFRiIgIk5VTExTV0FQSUZOT1QyIjsKKGludCwgc2xpY2UsIGludCkgaWRpY3RfZ2V0X21pbj8oY2VsbCBkaWN0LCBpbnQga2V5X2xl' + + 'bikgYXNtICgtPiAxIDAgMikgIkRJQ1RJTUlOIiAiTlVMTFNXQVBJRk5PVDIiOwooaW50LCBzbGljZSwgaW50KSBpZGljdF9nZXRfbWF4PyhjZWxsIGRpY3QsIGludCBr' + + 'ZXlfbGVuKSBhc20gKC0+IDEgMCAyKSAiRElDVElNQVgiICJOVUxMU1dBUElGTk9UMiI7CihpbnQsIGNlbGwsIGludCkgaWRpY3RfZ2V0X21pbl9yZWY/KGNlbGwgZGlj' + + 'dCwgaW50IGtleV9sZW4pIGFzbSAoLT4gMSAwIDIpICJESUNUSU1JTlJFRiIgIk5VTExTV0FQSUZOT1QyIjsKKGludCwgY2VsbCwgaW50KSBpZGljdF9nZXRfbWF4X3Jl' + + 'Zj8oY2VsbCBkaWN0LCBpbnQga2V5X2xlbikgYXNtICgtPiAxIDAgMikgIkRJQ1RJTUFYUkVGIiAiTlVMTFNXQVBJRk5PVDIiOwooaW50LCBzbGljZSwgaW50KSB1ZGlj' + + 'dF9nZXRfbmV4dD8oY2VsbCBkaWN0LCBpbnQga2V5X2xlbiwgaW50IHBpdm90KSBhc20ocGl2b3QgZGljdCBrZXlfbGVuIC0+IDEgMCAyKSAiRElDVFVHRVRORVhUIiAi' + + 'TlVMTFNXQVBJRk5PVDIiOwooaW50LCBzbGljZSwgaW50KSB1ZGljdF9nZXRfbmV4dGVxPyhjZWxsIGRpY3QsIGludCBrZXlfbGVuLCBpbnQgcGl2b3QpIGFzbShwaXZv' + + 'dCBkaWN0IGtleV9sZW4gLT4gMSAwIDIpICJESUNUVUdFVE5FWFRFUSIgIk5VTExTV0FQSUZOT1QyIjsKKGludCwgc2xpY2UsIGludCkgdWRpY3RfZ2V0X3ByZXY/KGNl' + + 'bGwgZGljdCwgaW50IGtleV9sZW4sIGludCBwaXZvdCkgYXNtKHBpdm90IGRpY3Qga2V5X2xlbiAtPiAxIDAgMikgIkRJQ1RVR0VUUFJFViIgIk5VTExTV0FQSUZOT1Qy' + + 'IjsKKGludCwgc2xpY2UsIGludCkgdWRpY3RfZ2V0X3ByZXZlcT8oY2VsbCBkaWN0LCBpbnQga2V5X2xlbiwgaW50IHBpdm90KSBhc20ocGl2b3QgZGljdCBrZXlfbGVu' + + 'IC0+IDEgMCAyKSAiRElDVFVHRVRQUkVWRVEiICJOVUxMU1dBUElGTk9UMiI7CihpbnQsIHNsaWNlLCBpbnQpIGlkaWN0X2dldF9uZXh0PyhjZWxsIGRpY3QsIGludCBr' + + 'ZXlfbGVuLCBpbnQgcGl2b3QpIGFzbShwaXZvdCBkaWN0IGtleV9sZW4gLT4gMSAwIDIpICJESUNUSUdFVE5FWFQiICJOVUxMU1dBUElGTk9UMiI7CihpbnQsIHNsaWNl' + + 'LCBpbnQpIGlkaWN0X2dldF9uZXh0ZXE/KGNlbGwgZGljdCwgaW50IGtleV9sZW4sIGludCBwaXZvdCkgYXNtKHBpdm90IGRpY3Qga2V5X2xlbiAtPiAxIDAgMikgIkRJ' + + 'Q1RJR0VUTkVYVEVRIiAiTlVMTFNXQVBJRk5PVDIiOwooaW50LCBzbGljZSwgaW50KSBpZGljdF9nZXRfcHJldj8oY2VsbCBkaWN0LCBpbnQga2V5X2xlbiwgaW50IHBp' + + 'dm90KSBhc20ocGl2b3QgZGljdCBrZXlfbGVuIC0+IDEgMCAyKSAiRElDVElHRVRQUkVWIiAiTlVMTFNXQVBJRk5PVDIiOwooaW50LCBzbGljZSwgaW50KSBpZGljdF9n' + + 'ZXRfcHJldmVxPyhjZWxsIGRpY3QsIGludCBrZXlfbGVuLCBpbnQgcGl2b3QpIGFzbShwaXZvdCBkaWN0IGtleV9sZW4gLT4gMSAwIDIpICJESUNUSUdFVFBSRVZFUSIg' + + 'Ik5VTExTV0FQSUZOT1QyIjsKCjs7OyBDcmVhdGVzIGFuIGVtcHR5IGRpY3Rpb25hcnksIHdoaWNoIGlzIGFjdHVhbGx5IGEgbnVsbCB2YWx1ZS4gRXF1aXZhbGVudCB0' + + 'byBQVVNITlVMTApjZWxsIG5ld19kaWN0KCkgYXNtICJORVdESUNUIjsKOzs7IENoZWNrcyB3aGV0aGVyIGEgZGljdGlvbmFyeSBpcyBlbXB0eS4gRXF1aXZhbGVudCB0' + + 'byBjZWxsX251bGw/LgppbnQgZGljdF9lbXB0eT8oY2VsbCBjKSBhc20gIkRJQ1RFTVBUWSI7CgoKey0gUHJlZml4IGRpY3Rpb25hcnkgcHJpbWl0aXZlcyAtfQooc2xp' + + 'Y2UsIHNsaWNlLCBzbGljZSwgaW50KSBwZnhkaWN0X2dldD8oY2VsbCBkaWN0LCBpbnQga2V5X2xlbiwgc2xpY2Uga2V5KSBhc20oa2V5IGRpY3Qga2V5X2xlbikgIlBG' + + 'WERJQ1RHRVRRIiAiTlVMTFNXQVBJRk5PVDIiOwooY2VsbCwgaW50KSBwZnhkaWN0X3NldD8oY2VsbCBkaWN0LCBpbnQga2V5X2xlbiwgc2xpY2Uga2V5LCBzbGljZSB2' + + 'YWx1ZSkgYXNtKHZhbHVlIGtleSBkaWN0IGtleV9sZW4pICJQRlhESUNUU0VUIjsKKGNlbGwsIGludCkgcGZ4ZGljdF9kZWxldGU/KGNlbGwgZGljdCwgaW50IGtleV9s' + + 'ZW4sIHNsaWNlIGtleSkgYXNtKGtleSBkaWN0IGtleV9sZW4pICJQRlhESUNUREVMIjsKCjs7OyBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgZ2xvYmFsIGNvbmZpZ3Vy' + + 'YXRpb24gcGFyYW1ldGVyIHdpdGggaW50ZWdlciBpbmRleCBgaWAgYXMgYSBgY2VsbGAgb3IgYG51bGxgIHZhbHVlLgpjZWxsIGNvbmZpZ19wYXJhbShpbnQgeCkgYXNt' + + 'ICJDT05GSUdPUFRQQVJBTSI7Cjs7OyBDaGVja3Mgd2hldGhlciBjIGlzIGEgbnVsbC4gTm90ZSwgdGhhdCBGdW5DIGFsc28gaGFzIHBvbHltb3JwaGljIG51bGw/IGJ1' + + 'aWx0LWluLgppbnQgY2VsbF9udWxsPyhjZWxsIGMpIGFzbSAiSVNOVUxMIjsKCjs7OyBDcmVhdGVzIGFuIG91dHB1dCBhY3Rpb24gd2hpY2ggd291bGQgcmVzZXJ2ZSBl' + + 'eGFjdGx5IGFtb3VudCBuYW5vdG9uY29pbnMgKGlmIG1vZGUgPSAwKSwgYXQgbW9zdCBhbW91bnQgbmFub3RvbmNvaW5zIChpZiBtb2RlID0gMiksIG9yIGFsbCBidXQg' + + 'YW1vdW50IG5hbm90b25jb2lucyAoaWYgbW9kZSA9IDEgb3IgbW9kZSA9IDMpLCBmcm9tIHRoZSByZW1haW5pbmcgYmFsYW5jZSBvZiB0aGUgYWNjb3VudC4gSXQgaXMg' + + 'cm91Z2hseSBlcXVpdmFsZW50IHRvIGNyZWF0aW5nIGFuIG91dGJvdW5kIG1lc3NhZ2UgY2FycnlpbmcgYW1vdW50IG5hbm90b25jb2lucyAob3IgYiDiiJIgYW1vdW50' + + 'IG5hbm90b25jb2lucywgd2hlcmUgYiBpcyB0aGUgcmVtYWluaW5nIGJhbGFuY2UpIHRvIG9uZXNlbGYsIHNvIHRoYXQgdGhlIHN1YnNlcXVlbnQgb3V0cHV0IGFjdGlv' + + 'bnMgd291bGQgbm90IGJlIGFibGUgdG8gc3BlbmQgbW9yZSBtb25leSB0aGFuIHRoZSByZW1haW5kZXIuIEJpdCArMiBpbiBtb2RlIG1lYW5zIHRoYXQgdGhlIGV4dGVy' + + 'bmFsIGFjdGlvbiBkb2VzIG5vdCBmYWlsIGlmIHRoZSBzcGVjaWZpZWQgYW1vdW50IGNhbm5vdCBiZSByZXNlcnZlZDsgaW5zdGVhZCwgYWxsIHJlbWFpbmluZyBiYWxh' + + 'bmNlIGlzIHJlc2VydmVkLiBCaXQgKzggaW4gbW9kZSBtZWFucyBgYW1vdW50IDwtIC1hbW91bnRgIGJlZm9yZSBwZXJmb3JtaW5nIGFueSBmdXJ0aGVyIGFjdGlvbnMu' + + 'IEJpdCArNCBpbiBtb2RlIG1lYW5zIHRoYXQgYW1vdW50IGlzIGluY3JlYXNlZCBieSB0aGUgb3JpZ2luYWwgYmFsYW5jZSBvZiB0aGUgY3VycmVudCBhY2NvdW50IChi' + + 'ZWZvcmUgdGhlIGNvbXB1dGUgcGhhc2UpLCBpbmNsdWRpbmcgYWxsIGV4dHJhIGN1cnJlbmNpZXMsIGJlZm9yZSBwZXJmb3JtaW5nIGFueSBvdGhlciBjaGVja3MgYW5k' + + 'IGFjdGlvbnMuIEN1cnJlbnRseSwgYW1vdW50IG11c3QgYmUgYSBub24tbmVnYXRpdmUgaW50ZWdlciwgYW5kIG1vZGUgbXVzdCBiZSBpbiB0aGUgcmFuZ2UgMC4uMTUu' + + 'CigpIHJhd19yZXNlcnZlKGludCBhbW91bnQsIGludCBtb2RlKSBpbXB1cmUgYXNtICJSQVdSRVNFUlZFIjsKOzs7IFNpbWlsYXIgdG8gcmF3X3Jlc2VydmUsIGJ1dCBh' + + 'bHNvIGFjY2VwdHMgYSBkaWN0aW9uYXJ5IGV4dHJhX2Ftb3VudCAocmVwcmVzZW50ZWQgYnkgYSBjZWxsIG9yIG51bGwpIHdpdGggZXh0cmEgY3VycmVuY2llcy4gSW4g' + + 'dGhpcyB3YXkgY3VycmVuY2llcyBvdGhlciB0aGFuIFRvbkNvaW4gY2FuIGJlIHJlc2VydmVkLgooKSByYXdfcmVzZXJ2ZV9leHRyYShpbnQgYW1vdW50LCBjZWxsIGV4' + + 'dHJhX2Ftb3VudCwgaW50IG1vZGUpIGltcHVyZSBhc20gIlJBV1JFU0VSVkVYIjsKOzs7IFNlbmRzIGEgcmF3IG1lc3NhZ2UgY29udGFpbmVkIGluIG1zZywgd2hpY2gg' + + 'c2hvdWxkIGNvbnRhaW4gYSBjb3JyZWN0bHkgc2VyaWFsaXplZCBvYmplY3QgTWVzc2FnZSBYLCB3aXRoIHRoZSBvbmx5IGV4Y2VwdGlvbiB0aGF0IHRoZSBzb3VyY2Ug' + + 'YWRkcmVzcyBpcyBhbGxvd2VkIHRvIGhhdmUgZHVtbXkgdmFsdWUgYWRkcl9ub25lICh0byBiZSBhdXRvbWF0aWNhbGx5IHJlcGxhY2VkIHdpdGggdGhlIGN1cnJlbnQg' + + 'c21hcnQgY29udHJhY3QgYWRkcmVzcyksIGFuZCBpaHJfZmVlLCBmd2RfZmVlLCBjcmVhdGVkX2x0IGFuZCBjcmVhdGVkX2F0IGZpZWxkcyBjYW4gaGF2ZSBhcmJpdHJh' + + 'cnkgdmFsdWVzICh0byBiZSByZXdyaXR0ZW4gd2l0aCBjb3JyZWN0IHZhbHVlcyBkdXJpbmcgdGhlIGFjdGlvbiBwaGFzZSBvZiB0aGUgY3VycmVudCB0cmFuc2FjdGlv' + + 'bikuIEludGVnZXIgcGFyYW1ldGVyIG1vZGUgY29udGFpbnMgdGhlIGZsYWdzLiBDdXJyZW50bHkgbW9kZSA9IDAgaXMgdXNlZCBmb3Igb3JkaW5hcnkgbWVzc2FnZXM7' + + 'IG1vZGUgPSAxMjggaXMgdXNlZCBmb3IgbWVzc2FnZXMgdGhhdCBhcmUgdG8gY2FycnkgYWxsIHRoZSByZW1haW5pbmcgYmFsYW5jZSBvZiB0aGUgY3VycmVudCBzbWFy' + + 'dCBjb250cmFjdCAoaW5zdGVhZCBvZiB0aGUgdmFsdWUgb3JpZ2luYWxseSBpbmRpY2F0ZWQgaW4gdGhlIG1lc3NhZ2UpOyBtb2RlID0gNjQgaXMgdXNlZCBmb3IgbWVz' + + 'c2FnZXMgdGhhdCBjYXJyeSBhbGwgdGhlIHJlbWFpbmluZyB2YWx1ZSBvZiB0aGUgaW5ib3VuZCBtZXNzYWdlIGluIGFkZGl0aW9uIHRvIHRoZSB2YWx1ZSBpbml0aWFs' + + 'bHkgaW5kaWNhdGVkIGluIHRoZSBuZXcgbWVzc2FnZSAoaWYgYml0IDAgaXMgbm90IHNldCwgdGhlIGdhcyBmZWVzIGFyZSBkZWR1Y3RlZCBmcm9tIHRoaXMgYW1vdW50' + + 'KTsgbW9kZScgPSBtb2RlICsgMSBtZWFucyB0aGF0IHRoZSBzZW5kZXIgd2FudHMgdG8gcGF5IHRyYW5zZmVyIGZlZXMgc2VwYXJhdGVseTsgbW9kZScgPSBtb2RlICsg' + + 'MiBtZWFucyB0aGF0IGFueSBlcnJvcnMgYXJpc2luZyB3aGlsZSBwcm9jZXNzaW5nIHRoaXMgbWVzc2FnZSBkdXJpbmcgdGhlIGFjdGlvbiBwaGFzZSBzaG91bGQgYmUg' + + 'aWdub3JlZC4gRmluYWxseSwgbW9kZScgPSBtb2RlICsgMzIgbWVhbnMgdGhhdCB0aGUgY3VycmVudCBhY2NvdW50IG11c3QgYmUgZGVzdHJveWVkIGlmIGl0cyByZXN1' + + 'bHRpbmcgYmFsYW5jZSBpcyB6ZXJvLiBUaGlzIGZsYWcgaXMgdXN1YWxseSBlbXBsb3llZCB0b2dldGhlciB3aXRoICsxMjguCigpIHNlbmRfcmF3X21lc3NhZ2UoY2Vs' + + 'bCBtc2csIGludCBtb2RlKSBpbXB1cmUgYXNtICJTRU5EUkFXTVNHIjsKOzs7IENyZWF0ZXMgYW4gb3V0cHV0IGFjdGlvbiB0aGF0IHdvdWxkIGNoYW5nZSB0aGlzIHNt' + + 'YXJ0IGNvbnRyYWN0IGNvZGUgdG8gdGhhdCBnaXZlbiBieSBjZWxsIG5ld19jb2RlLiBOb3RpY2UgdGhhdCB0aGlzIGNoYW5nZSB3aWxsIHRha2UgZWZmZWN0IG9ubHkg' + + 'YWZ0ZXIgdGhlIHN1Y2Nlc3NmdWwgdGVybWluYXRpb24gb2YgdGhlIGN1cnJlbnQgcnVuIG9mIHRoZSBzbWFydCBjb250cmFjdAooKSBzZXRfY29kZShjZWxsIG5ld19j' + + 'b2RlKSBpbXB1cmUgYXNtICJTRVRDT0RFIjsKCjs7OyBHZW5lcmF0ZXMgYSBuZXcgcHNldWRvLXJhbmRvbSB1bnNpZ25lZCAyNTYtYml0IGludGVnZXIgeC4gVGhlIGFs' + + 'Z29yaXRobSBpcyBhcyBmb2xsb3dzOiBpZiByIGlzIHRoZSBvbGQgdmFsdWUgb2YgdGhlIHJhbmRvbSBzZWVkLCBjb25zaWRlcmVkIGFzIGEgMzItYnl0ZSBhcnJheSAo' + + 'YnkgY29uc3RydWN0aW5nIHRoZSBiaWctZW5kaWFuIHJlcHJlc2VudGF0aW9uIG9mIGFuIHVuc2lnbmVkIDI1Ni1iaXQgaW50ZWdlciksIHRoZW4gaXRzIHNoYTUxMihy' + + 'KSBpcyBjb21wdXRlZDsgdGhlIGZpcnN0IDMyIGJ5dGVzIG9mIHRoaXMgaGFzaCBhcmUgc3RvcmVkIGFzIHRoZSBuZXcgdmFsdWUgcicgb2YgdGhlIHJhbmRvbSBzZWVk' + + 'LCBhbmQgdGhlIHJlbWFpbmluZyAzMiBieXRlcyBhcmUgcmV0dXJuZWQgYXMgdGhlIG5leHQgcmFuZG9tIHZhbHVlIHguCmludCByYW5kb20oKSBpbXB1cmUgYXNtICJS' + + 'QU5EVTI1NiI7Cjs7OyBHZW5lcmF0ZXMgYSBuZXcgcHNldWRvLXJhbmRvbSBpbnRlZ2VyIHogaW4gdGhlIHJhbmdlIDAuLnJhbmdl4oiSMSAob3IgcmFuZ2UuLuKIkjEs' + + 'IGlmIHJhbmdlIDwgMCkuIE1vcmUgcHJlY2lzZWx5LCBhbiB1bnNpZ25lZCByYW5kb20gdmFsdWUgeCBpcyBnZW5lcmF0ZWQgYXMgaW4gcmFuZG9tOyB0aGVuIHogOj0g' + + 'eCAqIHJhbmdlIC8gMl4yNTYgaXMgY29tcHV0ZWQuCmludCByYW5kKGludCByYW5nZSkgaW1wdXJlIGFzbSAiUkFORCI7Cjs7OyBSZXR1cm5zIHRoZSBjdXJyZW50IHJh' + + 'bmRvbSBzZWVkIGFzIGFuIHVuc2lnbmVkIDI1Ni1iaXQgSW50ZWdlci4KaW50IGdldF9zZWVkKCkgaW1wdXJlIGFzbSAiUkFORFNFRUQiOwo7OzsgU2V0cyB0aGUgcmFu' + + 'ZG9tIHNlZWQgdG8gdW5zaWduZWQgMjU2LWJpdCBzZWVkLgooKSBzZXRfc2VlZChpbnQgeCkgaW1wdXJlIGFzbSAiU0VUUkFORCI7Cjs7OyBNaXhlcyB1bnNpZ25lZCAy' + + 'NTYtYml0IGludGVnZXIgeCBpbnRvIHRoZSByYW5kb20gc2VlZCByIGJ5IHNldHRpbmcgdGhlIHJhbmRvbSBzZWVkIHRvIHNoYTI1NiBvZiB0aGUgY29uY2F0ZW5hdGlv' + + 'biBvZiB0d28gMzItYnl0ZSBzdHJpbmdzOiB0aGUgZmlyc3Qgd2l0aCB0aGUgYmlnLWVuZGlhbiByZXByZXNlbnRhdGlvbiBvZiB0aGUgb2xkIHNlZWQgciwgYW5kIHRo' + + 'ZSBzZWNvbmQgd2l0aCB0aGUgYmlnLWVuZGlhbiByZXByZXNlbnRhdGlvbiBvZiB4LgooKSByYW5kb21pemUoaW50IHgpIGltcHVyZSBhc20gIkFERFJBTkQiOwo7Ozsg' + + 'RXF1aXZhbGVudCB0byByYW5kb21pemUoY3VyX2x0KCkpOy4KKCkgcmFuZG9taXplX2x0KCkgaW1wdXJlIGFzbSAiTFRJTUUiICJBRERSQU5EIjsKCjs7OyBDaGVja3Mg' + + 'd2hldGhlciB0aGUgZGF0YSBwYXJ0cyBvZiB0d28gc2xpY2VzIGNvaW5zaWRlCmludCBlcXVhbF9zbGljZXNfYml0cyhzbGljZSBhLCBzbGljZSBiKSBhc20gIlNERVEi' + + 'Owo7OzsgQ2hlY2tzIHdoZXRoZXIgYiBpcyBhIG51bGwuIE5vdGUsIHRoYXQgRnVuQyBhbHNvIGhhcyBwb2x5bW9ycGhpYyBudWxsPyBidWlsdC1pbi4KaW50IGJ1aWxk' + + 'ZXJfbnVsbD8oYnVpbGRlciBiKSBhc20gIklTTlVMTCI7Cjs7OyBDb25jYXRlbmF0ZXMgdHdvIGJ1aWxkZXJzCmJ1aWxkZXIgc3RvcmVfYnVpbGRlcihidWlsZGVyIHRv' + + 'LCBidWlsZGVyIGZyb20pIGFzbSAiU1RCUiI7Cgo7OyBDVVNUT006Cgo7OyBUVk0gVVBHUkFERSAyMDIzLTA3IGh0dHBzOi8vZG9jcy50b24ub3JnL2xlYXJuL3R2bS1p' + + 'bnN0cnVjdGlvbnMvdHZtLXVwZ3JhZGUtMjAyMy0wNwo7OyBJbiBtYWlubmV0IHNpbmNlIDIwIERlYyAyMDIzIGh0dHBzOi8vdC5tZS90b25ibG9ja2NoYWluLzIyNgoK' + + 'Ozs7IFJldHJpZXZlcyBjb2RlIG9mIHNtYXJ0LWNvbnRyYWN0IGZyb20gYzcKY2VsbCBteV9jb2RlKCkgYXNtICJNWUNPREUiOwo='; files['stdlib.tact'] = 'aW1wb3J0ICIuL3N0ZC9wcmltaXRpdmVzIjsKaW1wb3J0ICIuL3N0ZC9jZWxscyI7CmltcG9ydCAiLi9zdGQvY3J5cHRvIjsKaW1wb3J0ICIuL3N0ZC90ZXh0IjsKaW1w' + 'b3J0ICIuL3N0ZC9tYXRoIjsKaW1wb3J0ICIuL3N0ZC9jb250cmFjdCI7CmltcG9ydCAiLi9zdGQvZGVidWciOwppbXBvcnQgIi4vc3RkL2NvbnRleHQiOwppbXBvcnQg' + diff --git a/src/test/e2e-emulated/contracts/maps.tact b/src/test/e2e-emulated/contracts/maps.tact index 15c537cc5..64ddf2f8e 100644 --- a/src/test/e2e-emulated/contracts/maps.tact +++ b/src/test/e2e-emulated/contracts/maps.tact @@ -1,1032 +1,1932 @@ -message SetIntMap1 { - key: Int; - value: Int?; -} - -message SetIntMap2 { - key: Int; - value: Bool?; -} - -message SetIntMap3 { - key: Int; - value: Cell?; -} - -message SetIntMap4 { - key: Int; - value: SomeStruct?; -} - -message SetIntMap5 { - key: Int; - value: Address?; -} - -message SetIntMap6 { - key: Int; - value: Int?; -} - -message SetUIntMap7 { - key: Int; - value: Int?; -} - -message SetIntMap8 { - key: Int; - value: Int?; -} - -message SetUIntMap9 { - key: Int; - value: Int?; -} - -message SetUIntMap10 { - key: Int; - value: Int?; -} - -message SetAddrMap1 { - key: Address; - value: Int?; -} - -message SetAddrMap2 { - key: Address; - value: Bool?; -} - -message SetAddrMap3 { - key: Address; - value: Cell?; -} - -message SetAddrMap4 { - key: Address; - value: SomeStruct?; -} - -message SetAddrMap5 { - key: Address; - value: Address?; -} - -message SetAddrMap6 { - key: Address; - value: Int?; -} - -message SetAddrMap7 { - key: Address; - value: Int?; -} - +// struct with over 1023 bits so that it is serialized as multiple cells struct SomeStruct { - value: Int; -} - -message DelIntMap1 { - key: Int; + int: Int; + bool: Bool; + address: Address; + a: Int; + b: Int; } -message DelIntMap2 { - key: Int; +// =============================== +// Structs For Getters +// =============================== + +struct GetAllMapsResult { + // Integer Key Maps + int_int: Int?; + int_int8: Int?; + int_int42: Int?; + int_int256: Int?; + int_uint8: Int?; + int_uint42: Int?; + int_uint256: Int?; + int_bool: Bool?; + int_cell: Cell?; + int_address: Address?; + int_struct: SomeStruct?; + + int8_int: Int?; + int8_int8: Int?; + int8_int42: Int?; + int8_int256: Int?; + int8_uint8: Int?; + int8_uint42: Int?; + int8_uint256: Int?; + int8_bool: Bool?; + int8_cell: Cell?; + int8_address: Address?; + int8_struct: SomeStruct?; + + int42_int: Int?; + int42_int8: Int?; + int42_int42: Int?; + int42_int256: Int?; + int42_uint8: Int?; + int42_uint42: Int?; + int42_uint256: Int?; + int42_bool: Bool?; + int42_cell: Cell?; + int42_address: Address?; + int42_struct: SomeStruct?; + + int256_int: Int?; + int256_int8: Int?; + int256_int42: Int?; + int256_int256: Int?; + int256_uint8: Int?; + int256_uint42: Int?; + int256_uint256: Int?; + int256_bool: Bool?; + int256_cell: Cell?; + int256_address: Address?; + int256_struct: SomeStruct?; + + uint8_int: Int?; + uint8_int8: Int?; + uint8_int42: Int?; + uint8_int256: Int?; + uint8_uint8: Int?; + uint8_uint42: Int?; + uint8_uint256: Int?; + uint8_bool: Bool?; + uint8_cell: Cell?; + uint8_address: Address?; + uint8_struct: SomeStruct?; + + uint42_int: Int?; + uint42_int8: Int?; + uint42_int42: Int?; + uint42_int256: Int?; + uint42_uint8: Int?; + uint42_uint42: Int?; + uint42_uint256: Int?; + uint42_bool: Bool?; + uint42_cell: Cell?; + uint42_address: Address?; + uint42_struct: SomeStruct?; + + uint256_int: Int?; + uint256_int8: Int?; + uint256_int42: Int?; + uint256_int256: Int?; + uint256_uint8: Int?; + uint256_uint42: Int?; + uint256_uint256: Int?; + uint256_bool: Bool?; + uint256_cell: Cell?; + uint256_address: Address?; + uint256_struct: SomeStruct?; + + // Address Key Maps + address_int: Int?; + address_int8: Int?; + address_int42: Int?; + address_int256: Int?; + address_uint8: Int?; + address_uint42: Int?; + address_uint256: Int?; + address_bool: Bool?; + address_cell: Cell?; + address_address: Address?; + address_struct: SomeStruct?; } -message DelIntMap3 { - key: Int; +struct ReplaceAllMapsResult { + // Integer Key Maps + int_int: Bool; + int_int8: Bool; + int_int42: Bool; + int_int256: Bool; + int_uint8: Bool; + int_uint42: Bool; + int_uint256: Bool; + int_bool: Bool; + int_cell: Bool; + int_address: Bool; + int_struct: Bool; + + int8_int: Bool; + int8_int8: Bool; + int8_int42: Bool; + int8_int256: Bool; + int8_uint8: Bool; + int8_uint42: Bool; + int8_uint256: Bool; + int8_bool: Bool; + int8_cell: Bool; + int8_address: Bool; + int8_struct: Bool; + + int42_int: Bool; + int42_int8: Bool; + int42_int42: Bool; + int42_int256: Bool; + int42_uint8: Bool; + int42_uint42: Bool; + int42_uint256: Bool; + int42_bool: Bool; + int42_cell: Bool; + int42_address: Bool; + int42_struct: Bool; + + int256_int: Bool; + int256_int8: Bool; + int256_int42: Bool; + int256_int256: Bool; + int256_uint8: Bool; + int256_uint42: Bool; + int256_uint256: Bool; + int256_bool: Bool; + int256_cell: Bool; + int256_address: Bool; + int256_struct: Bool; + + uint8_int: Bool; + uint8_int8: Bool; + uint8_int42: Bool; + uint8_int256: Bool; + uint8_uint8: Bool; + uint8_uint42: Bool; + uint8_uint256: Bool; + uint8_bool: Bool; + uint8_cell: Bool; + uint8_address: Bool; + uint8_struct: Bool; + + uint42_int: Bool; + uint42_int8: Bool; + uint42_int42: Bool; + uint42_int256: Bool; + uint42_uint8: Bool; + uint42_uint42: Bool; + uint42_uint256: Bool; + uint42_bool: Bool; + uint42_cell: Bool; + uint42_address: Bool; + uint42_struct: Bool; + + uint256_int: Bool; + uint256_int8: Bool; + uint256_int42: Bool; + uint256_int256: Bool; + uint256_uint8: Bool; + uint256_uint42: Bool; + uint256_uint256: Bool; + uint256_bool: Bool; + uint256_cell: Bool; + uint256_address: Bool; + uint256_struct: Bool; + + // Address Key Maps + address_int: Bool; + address_int8: Bool; + address_int42: Bool; + address_int256: Bool; + address_uint8: Bool; + address_uint42: Bool; + address_uint256: Bool; + address_bool: Bool; + address_cell: Bool; + address_address: Bool; + address_struct: Bool; } -message DelIntMap4 { - key: Int; +struct ReplaceGetAllMapsResult { + // Integer Key Maps + int_int: Int?; + int_int8: Int?; + int_int42: Int?; + int_int256: Int?; + int_uint8: Int?; + int_uint42: Int?; + int_uint256: Int?; + int_bool: Bool?; + int_cell: Cell?; + int_address: Address?; + int_struct: SomeStruct?; + + int8_int: Int?; + int8_int8: Int?; + int8_int42: Int?; + int8_int256: Int?; + int8_uint8: Int?; + int8_uint42: Int?; + int8_uint256: Int?; + int8_bool: Bool?; + int8_cell: Cell?; + int8_address: Address?; + int8_struct: SomeStruct?; + + int42_int: Int?; + int42_int8: Int?; + int42_int42: Int?; + int42_int256: Int?; + int42_uint8: Int?; + int42_uint42: Int?; + int42_uint256: Int?; + int42_bool: Bool?; + int42_cell: Cell?; + int42_address: Address?; + int42_struct: SomeStruct?; + + int256_int: Int?; + int256_int8: Int?; + int256_int42: Int?; + int256_int256: Int?; + int256_uint8: Int?; + int256_uint42: Int?; + int256_uint256: Int?; + int256_bool: Bool?; + int256_cell: Cell?; + int256_address: Address?; + int256_struct: SomeStruct?; + + uint8_int: Int?; + uint8_int8: Int?; + uint8_int42: Int?; + uint8_int256: Int?; + uint8_uint8: Int?; + uint8_uint42: Int?; + uint8_uint256: Int?; + uint8_bool: Bool?; + uint8_cell: Cell?; + uint8_address: Address?; + uint8_struct: SomeStruct?; + + uint42_int: Int?; + uint42_int8: Int?; + uint42_int42: Int?; + uint42_int256: Int?; + uint42_uint8: Int?; + uint42_uint42: Int?; + uint42_uint256: Int?; + uint42_bool: Bool?; + uint42_cell: Cell?; + uint42_address: Address?; + uint42_struct: SomeStruct?; + + uint256_int: Int?; + uint256_int8: Int?; + uint256_int42: Int?; + uint256_int256: Int?; + uint256_uint8: Int?; + uint256_uint42: Int?; + uint256_uint256: Int?; + uint256_bool: Bool?; + uint256_cell: Cell?; + uint256_address: Address?; + uint256_struct: SomeStruct?; + + // Address Key Maps + address_int: Int?; + address_int8: Int?; + address_int42: Int?; + address_int256: Int?; + address_uint8: Int?; + address_uint42: Int?; + address_uint256: Int?; + address_bool: Bool?; + address_cell: Cell?; + address_address: Address?; + address_struct: SomeStruct?; } -message DelIntMap5 { - key: Int; +struct ExistsAllMapsResult { + // Integer Key Maps + int_int: Bool; + int_int8: Bool; + int_int42: Bool; + int_int256: Bool; + int_uint8: Bool; + int_uint42: Bool; + int_uint256: Bool; + int_bool: Bool; + int_cell: Bool; + int_address: Bool; + int_struct: Bool; + + int8_int: Bool; + int8_int8: Bool; + int8_int42: Bool; + int8_int256: Bool; + int8_uint8: Bool; + int8_uint42: Bool; + int8_uint256: Bool; + int8_bool: Bool; + int8_cell: Bool; + int8_address: Bool; + int8_struct: Bool; + + int42_int: Bool; + int42_int8: Bool; + int42_int42: Bool; + int42_int256: Bool; + int42_uint8: Bool; + int42_uint42: Bool; + int42_uint256: Bool; + int42_bool: Bool; + int42_cell: Bool; + int42_address: Bool; + int42_struct: Bool; + + int256_int: Bool; + int256_int8: Bool; + int256_int42: Bool; + int256_int256: Bool; + int256_uint8: Bool; + int256_uint42: Bool; + int256_uint256: Bool; + int256_bool: Bool; + int256_cell: Bool; + int256_address: Bool; + int256_struct: Bool; + + uint8_int: Bool; + uint8_int8: Bool; + uint8_int42: Bool; + uint8_int256: Bool; + uint8_uint8: Bool; + uint8_uint42: Bool; + uint8_uint256: Bool; + uint8_bool: Bool; + uint8_cell: Bool; + uint8_address: Bool; + uint8_struct: Bool; + + uint42_int: Bool; + uint42_int8: Bool; + uint42_int42: Bool; + uint42_int256: Bool; + uint42_uint8: Bool; + uint42_uint42: Bool; + uint42_uint256: Bool; + uint42_bool: Bool; + uint42_cell: Bool; + uint42_address: Bool; + uint42_struct: Bool; + + uint256_int: Bool; + uint256_int8: Bool; + uint256_int42: Bool; + uint256_int256: Bool; + uint256_uint8: Bool; + uint256_uint42: Bool; + uint256_uint256: Bool; + uint256_bool: Bool; + uint256_cell: Bool; + uint256_address: Bool; + uint256_struct: Bool; + + // Address Key Maps + address_int: Bool; + address_int8: Bool; + address_int42: Bool; + address_int256: Bool; + address_uint8: Bool; + address_uint42: Bool; + address_uint256: Bool; + address_bool: Bool; + address_cell: Bool; + address_address: Bool; + address_struct: Bool; } -message DelIntMap6 { - key: Int; +struct IsEmptyAllMapsResult { + // Integer Key Maps + int_int: Bool; + int_int8: Bool; + int_int42: Bool; + int_int256: Bool; + int_uint8: Bool; + int_uint42: Bool; + int_uint256: Bool; + int_bool: Bool; + int_cell: Bool; + int_address: Bool; + int_struct: Bool; + + int8_int: Bool; + int8_int8: Bool; + int8_int42: Bool; + int8_int256: Bool; + int8_uint8: Bool; + int8_uint42: Bool; + int8_uint256: Bool; + int8_bool: Bool; + int8_cell: Bool; + int8_address: Bool; + int8_struct: Bool; + + int42_int: Bool; + int42_int8: Bool; + int42_int42: Bool; + int42_int256: Bool; + int42_uint8: Bool; + int42_uint42: Bool; + int42_uint256: Bool; + int42_bool: Bool; + int42_cell: Bool; + int42_address: Bool; + int42_struct: Bool; + + int256_int: Bool; + int256_int8: Bool; + int256_int42: Bool; + int256_int256: Bool; + int256_uint8: Bool; + int256_uint42: Bool; + int256_uint256: Bool; + int256_bool: Bool; + int256_cell: Bool; + int256_address: Bool; + int256_struct: Bool; + + uint8_int: Bool; + uint8_int8: Bool; + uint8_int42: Bool; + uint8_int256: Bool; + uint8_uint8: Bool; + uint8_uint42: Bool; + uint8_uint256: Bool; + uint8_bool: Bool; + uint8_cell: Bool; + uint8_address: Bool; + uint8_struct: Bool; + + uint42_int: Bool; + uint42_int8: Bool; + uint42_int42: Bool; + uint42_int256: Bool; + uint42_uint8: Bool; + uint42_uint42: Bool; + uint42_uint256: Bool; + uint42_bool: Bool; + uint42_cell: Bool; + uint42_address: Bool; + uint42_struct: Bool; + + uint256_int: Bool; + uint256_int8: Bool; + uint256_int42: Bool; + uint256_int256: Bool; + uint256_uint8: Bool; + uint256_uint42: Bool; + uint256_uint256: Bool; + uint256_bool: Bool; + uint256_cell: Bool; + uint256_address: Bool; + uint256_struct: Bool; + + // Address Key Maps + address_int: Bool; + address_int8: Bool; + address_int42: Bool; + address_int256: Bool; + address_uint8: Bool; + address_uint42: Bool; + address_uint256: Bool; + address_bool: Bool; + address_cell: Bool; + address_address: Bool; + address_struct: Bool; } -message DelUIntMap7 { - key: Int; +struct AsCellAllMapsResult { + // Integer Key Maps + int_int: Cell?; + int_int8: Cell?; + int_int42: Cell?; + int_int256: Cell?; + int_uint8: Cell?; + int_uint42: Cell?; + int_uint256: Cell?; + int_bool: Cell?; + int_cell: Cell?; + int_address: Cell?; + int_struct: Cell?; + + int8_int: Cell?; + int8_int8: Cell?; + int8_int42: Cell?; + int8_int256: Cell?; + int8_uint8: Cell?; + int8_uint42: Cell?; + int8_uint256: Cell?; + int8_bool: Cell?; + int8_cell: Cell?; + int8_address: Cell?; + int8_struct: Cell?; + + int42_int: Cell?; + int42_int8: Cell?; + int42_int42: Cell?; + int42_int256: Cell?; + int42_uint8: Cell?; + int42_uint42: Cell?; + int42_uint256: Cell?; + int42_bool: Cell?; + int42_cell: Cell?; + int42_address: Cell?; + int42_struct: Cell?; + + int256_int: Cell?; + int256_int8: Cell?; + int256_int42: Cell?; + int256_int256: Cell?; + int256_uint8: Cell?; + int256_uint42: Cell?; + int256_uint256: Cell?; + int256_bool: Cell?; + int256_cell: Cell?; + int256_address: Cell?; + int256_struct: Cell?; + + uint8_int: Cell?; + uint8_int8: Cell?; + uint8_int42: Cell?; + uint8_int256: Cell?; + uint8_uint8: Cell?; + uint8_uint42: Cell?; + uint8_uint256: Cell?; + uint8_bool: Cell?; + uint8_cell: Cell?; + uint8_address: Cell?; + uint8_struct: Cell?; + + uint42_int: Cell?; + uint42_int8: Cell?; + uint42_int42: Cell?; + uint42_int256: Cell?; + uint42_uint8: Cell?; + uint42_uint42: Cell?; + uint42_uint256: Cell?; + uint42_bool: Cell?; + uint42_cell: Cell?; + uint42_address: Cell?; + uint42_struct: Cell?; + + uint256_int: Cell?; + uint256_int8: Cell?; + uint256_int42: Cell?; + uint256_int256: Cell?; + uint256_uint8: Cell?; + uint256_uint42: Cell?; + uint256_uint256: Cell?; + uint256_bool: Cell?; + uint256_cell: Cell?; + uint256_address: Cell?; + uint256_struct: Cell?; + + // Address Key Maps + address_int: Cell?; + address_int8: Cell?; + address_int42: Cell?; + address_int256: Cell?; + address_uint8: Cell?; + address_uint42: Cell?; + address_uint256: Cell?; + address_bool: Cell?; + address_cell: Cell?; + address_address: Cell?; + address_struct: Cell?; } -message DelIntMap8 { - key: Int; +// =============================== +// Messages For Operations +// =============================== + +message SetAllMaps { + // Key fields + keyInt: Int; + keyInt8: Int; + keyInt42: Int; + keyInt256: Int; + keyUint8: Int; + keyUint42: Int; + keyUint256: Int; + keyAddress: Address; + + // Value fields + valueInt: Int?; + valueInt8: Int?; + valueInt42: Int?; + valueInt256: Int?; + valueUint8: Int?; + valueUint42: Int?; + valueUint256: Int?; + valueBool: Bool?; + valueCell: Cell?; + valueAddress: Address?; + valueStruct: SomeStruct?; } -message DelUIntMap9 { - key: Int; +message DelAllMaps { + // Key fields + keyInt: Int; + keyInt8: Int; + keyInt42: Int; + keyInt256: Int; + keyUint8: Int; + keyUint42: Int; + keyUint256: Int; + keyAddress: Address; } -message DelUIntMap10 { - key: Int; +message ReplaceAllMaps { + // Key fields + keyInt: Int; + keyInt8: Int; + keyInt42: Int; + keyInt256: Int; + keyUint8: Int; + keyUint42: Int; + keyUint256: Int; + keyAddress: Address; + + // Value fields + valueInt: Int?; + valueInt8: Int?; + valueInt42: Int?; + valueInt256: Int?; + valueUint8: Int?; + valueUint42: Int?; + valueUint256: Int?; + valueBool: Bool?; + valueCell: Cell?; + valueAddress: Address?; + valueStruct: SomeStruct?; } -message DelAddrMap1 { - key: Address; +message ReplaceGetAllMaps { + // Key fields + keyInt: Int; + keyInt8: Int; + keyInt42: Int; + keyInt256: Int; + keyUint8: Int; + keyUint42: Int; + keyUint256: Int; + keyAddress: Address; + + // Value fields + valueInt: Int?; + valueInt8: Int?; + valueInt42: Int?; + valueInt256: Int?; + valueUint8: Int?; + valueUint42: Int?; + valueUint256: Int?; + valueBool: Bool?; + valueCell: Cell?; + valueAddress: Address?; + valueStruct: SomeStruct?; } -message DelAddrMap2 { - key: Address; -} - -message DelAddrMap3 { - key: Address; -} - -message DelAddrMap4 { - key: Address; -} - -message DelAddrMap5 { - key: Address; -} - -message DelAddrMap6 { - key: Address; -} - -message DelAddrMap7 { - key: Address; +message CheckNullReference { + } -message CheckNullReference {} +// =============================== +// Test Contract +// =============================== contract MapTestContract { - - init() { - // Nothing to do - } - - receive() { - // Nothing to do + receive() {} + + // =============================== + // Integer (`Int`) Key Maps + // =============================== + + int_int: map; + int_int8: map; + int_int42: map; + int_int256: map; + int_uint8: map; + int_uint42: map; + int_uint256: map; + int_bool: map; + int_cell: map; + int_address: map; + int_struct: map; + + // =============================== + // Integer (`Int as int8`) Key Maps + // =============================== + + int8_int: map; + int8_int8: map; + int8_int42: map; + int8_int256: map; + int8_uint8: map; + int8_uint42: map; + int8_uint256: map; + int8_bool: map; + int8_cell: map; + int8_address: map; + int8_struct: map; + + // =============================== + // Integer (`Int as int42`) Key Maps + // =============================== + + int42_int: map; + int42_int8: map; + int42_int42: map; + int42_int256: map; + int42_uint8: map; + int42_uint42: map; + int42_uint256: map; + int42_bool: map; + int42_cell: map; + int42_address: map; + int42_struct: map; + + // =============================== + // Integer (`Int as int256`) Key Maps + // =============================== + + int256_int: map; + int256_int8: map; + int256_int42: map; + int256_int256: map; + int256_uint8: map; + int256_uint42: map; + int256_uint256: map; + int256_bool: map; + int256_cell: map; + int256_address: map; + int256_struct: map; + + // =============================== + // Unsigned Integer (`Int as uint8`) Key Maps + // =============================== + + uint8_int: map; + uint8_int8: map; + uint8_int42: map; + uint8_int256: map; + uint8_uint8: map; + uint8_uint42: map; + uint8_uint256: map; + uint8_bool: map; + uint8_cell: map; + uint8_address: map; + uint8_struct: map; + + // =============================== + // Unsigned Integer (`Int as uint42`) Key Maps + // =============================== + + uint42_int: map; + uint42_int8: map; + uint42_int42: map; + uint42_int256: map; + uint42_uint8: map; + uint42_uint42: map; + uint42_uint256: map; + uint42_bool: map; + uint42_cell: map; + uint42_address: map; + uint42_struct: map; + + // =============================== + // Unsigned Integer (`Int as uint256`) Key Maps + // =============================== + + uint256_int: map; + uint256_int8: map; + uint256_int42: map; + uint256_int256: map; + uint256_uint8: map; + uint256_uint42: map; + uint256_uint256: map; + uint256_bool: map; + uint256_cell: map; + uint256_address: map; + uint256_struct: map; + + // =============================== + // Address Key Maps + // =============================== + + address_int: map; + address_int8: map; + address_int42: map; + address_int256: map; + address_uint8: map; + address_uint42: map; + address_uint256: map; + address_bool: map; + address_cell: map; + address_address: map; + address_struct: map; + + // =============================== + // Receivers For Operations + // =============================== + + receive(msg: SetAllMaps) { + // Integer Key Maps + self.int_int.set(msg.keyInt, msg.valueInt); + self.int_int8.set(msg.keyInt, msg.valueInt8); + self.int_int42.set(msg.keyInt, msg.valueInt42); + self.int_int256.set(msg.keyInt, msg.valueInt256); + self.int_uint8.set(msg.keyInt, msg.valueUint8); + self.int_uint42.set(msg.keyInt, msg.valueUint42); + self.int_uint256.set(msg.keyInt, msg.valueUint256); + self.int_bool.set(msg.keyInt, msg.valueBool); + self.int_cell.set(msg.keyInt, msg.valueCell); + self.int_address.set(msg.keyInt, msg.valueAddress); + self.int_struct.set(msg.keyInt, msg.valueStruct); + + self.int8_int.set(msg.keyInt8, msg.valueInt); + self.int8_int8.set(msg.keyInt8, msg.valueInt8); + self.int8_int42.set(msg.keyInt8, msg.valueInt42); + self.int8_int256.set(msg.keyInt8, msg.valueInt256); + self.int8_uint8.set(msg.keyInt8, msg.valueUint8); + self.int8_uint42.set(msg.keyInt8, msg.valueUint42); + self.int8_uint256.set(msg.keyInt8, msg.valueUint256); + self.int8_bool.set(msg.keyInt8, msg.valueBool); + self.int8_cell.set(msg.keyInt8, msg.valueCell); + self.int8_address.set(msg.keyInt8, msg.valueAddress); + self.int8_struct.set(msg.keyInt8, msg.valueStruct); + + self.int42_int.set(msg.keyInt42, msg.valueInt); + self.int42_int8.set(msg.keyInt42, msg.valueInt8); + self.int42_int42.set(msg.keyInt42, msg.valueInt42); + self.int42_int256.set(msg.keyInt42, msg.valueInt256); + self.int42_uint8.set(msg.keyInt42, msg.valueUint8); + self.int42_uint42.set(msg.keyInt42, msg.valueUint42); + self.int42_uint256.set(msg.keyInt42, msg.valueUint256); + self.int42_bool.set(msg.keyInt42, msg.valueBool); + self.int42_cell.set(msg.keyInt42, msg.valueCell); + self.int42_address.set(msg.keyInt42, msg.valueAddress); + self.int42_struct.set(msg.keyInt42, msg.valueStruct); + + self.int256_int.set(msg.keyInt256, msg.valueInt); + self.int256_int8.set(msg.keyInt256, msg.valueInt8); + self.int256_int42.set(msg.keyInt256, msg.valueInt42); + self.int256_int256.set(msg.keyInt256, msg.valueInt256); + self.int256_uint8.set(msg.keyInt256, msg.valueUint8); + self.int256_uint42.set(msg.keyInt256, msg.valueUint42); + self.int256_uint256.set(msg.keyInt256, msg.valueUint256); + self.int256_bool.set(msg.keyInt256, msg.valueBool); + self.int256_cell.set(msg.keyInt256, msg.valueCell); + self.int256_address.set(msg.keyInt256, msg.valueAddress); + self.int256_struct.set(msg.keyInt256, msg.valueStruct); + + self.uint8_int.set(msg.keyUint8, msg.valueInt); + self.uint8_int8.set(msg.keyUint8, msg.valueInt8); + self.uint8_int42.set(msg.keyUint8, msg.valueInt42); + self.uint8_int256.set(msg.keyUint8, msg.valueInt256); + self.uint8_uint8.set(msg.keyUint8, msg.valueUint8); + self.uint8_uint42.set(msg.keyUint8, msg.valueUint42); + self.uint8_uint256.set(msg.keyUint8, msg.valueUint256); + self.uint8_bool.set(msg.keyUint8, msg.valueBool); + self.uint8_cell.set(msg.keyUint8, msg.valueCell); + self.uint8_address.set(msg.keyUint8, msg.valueAddress); + self.uint8_struct.set(msg.keyUint8, msg.valueStruct); + + self.uint42_int.set(msg.keyUint42, msg.valueInt); + self.uint42_int8.set(msg.keyUint42, msg.valueInt8); + self.uint42_int42.set(msg.keyUint42, msg.valueInt42); + self.uint42_int256.set(msg.keyUint42, msg.valueInt256); + self.uint42_uint8.set(msg.keyUint42, msg.valueUint8); + self.uint42_uint42.set(msg.keyUint42, msg.valueUint42); + self.uint42_uint256.set(msg.keyUint42, msg.valueUint256); + self.uint42_bool.set(msg.keyUint42, msg.valueBool); + self.uint42_cell.set(msg.keyUint42, msg.valueCell); + self.uint42_address.set(msg.keyUint42, msg.valueAddress); + self.uint42_struct.set(msg.keyUint42, msg.valueStruct); + + self.uint256_int.set(msg.keyUint256, msg.valueInt); + self.uint256_int8.set(msg.keyUint256, msg.valueInt8); + self.uint256_int42.set(msg.keyUint256, msg.valueInt42); + self.uint256_int256.set(msg.keyUint256, msg.valueInt256); + self.uint256_uint8.set(msg.keyUint256, msg.valueUint8); + self.uint256_uint42.set(msg.keyUint256, msg.valueUint42); + self.uint256_uint256.set(msg.keyUint256, msg.valueUint256); + self.uint256_bool.set(msg.keyUint256, msg.valueBool); + self.uint256_cell.set(msg.keyUint256, msg.valueCell); + self.uint256_address.set(msg.keyUint256, msg.valueAddress); + self.uint256_struct.set(msg.keyUint256, msg.valueStruct); + + // Address Key Maps + self.address_int.set(msg.keyAddress, msg.valueInt); + self.address_int8.set(msg.keyAddress, msg.valueInt8); + self.address_int42.set(msg.keyAddress, msg.valueInt42); + self.address_int256.set(msg.keyAddress, msg.valueInt256); + self.address_uint8.set(msg.keyAddress, msg.valueUint8); + self.address_uint42.set(msg.keyAddress, msg.valueUint42); + self.address_uint256.set(msg.keyAddress, msg.valueUint256); + self.address_bool.set(msg.keyAddress, msg.valueBool); + self.address_cell.set(msg.keyAddress, msg.valueCell); + self.address_address.set(msg.keyAddress, msg.valueAddress); + self.address_struct.set(msg.keyAddress, msg.valueStruct); + } + + receive(msg: DelAllMaps) { + // Integer Key Maps + self.int_int.del(msg.keyInt); + self.int_int8.del(msg.keyInt); + self.int_int42.del(msg.keyInt); + self.int_int256.del(msg.keyInt); + self.int_uint8.del(msg.keyInt); + self.int_uint42.del(msg.keyInt); + self.int_uint256.del(msg.keyInt); + self.int_bool.del(msg.keyInt); + self.int_cell.del(msg.keyInt); + self.int_address.del(msg.keyInt); + self.int_struct.del(msg.keyInt); + + self.int8_int.del(msg.keyInt8); + self.int8_int8.del(msg.keyInt8); + self.int8_int42.del(msg.keyInt8); + self.int8_int256.del(msg.keyInt8); + self.int8_uint8.del(msg.keyInt8); + self.int8_uint42.del(msg.keyInt8); + self.int8_uint256.del(msg.keyInt8); + self.int8_bool.del(msg.keyInt8); + self.int8_cell.del(msg.keyInt8); + self.int8_address.del(msg.keyInt8); + self.int8_struct.del(msg.keyInt8); + + self.int42_int.del(msg.keyInt42); + self.int42_int8.del(msg.keyInt42); + self.int42_int42.del(msg.keyInt42); + self.int42_int256.del(msg.keyInt42); + self.int42_uint8.del(msg.keyInt42); + self.int42_uint42.del(msg.keyInt42); + self.int42_uint256.del(msg.keyInt42); + self.int42_bool.del(msg.keyInt42); + self.int42_cell.del(msg.keyInt42); + self.int42_address.del(msg.keyInt42); + self.int42_struct.del(msg.keyInt42); + + self.int256_int.del(msg.keyInt256); + self.int256_int8.del(msg.keyInt256); + self.int256_int42.del(msg.keyInt256); + self.int256_int256.del(msg.keyInt256); + self.int256_uint8.del(msg.keyInt256); + self.int256_uint42.del(msg.keyInt256); + self.int256_uint256.del(msg.keyInt256); + self.int256_bool.del(msg.keyInt256); + self.int256_cell.del(msg.keyInt256); + self.int256_address.del(msg.keyInt256); + self.int256_struct.del(msg.keyInt256); + + self.uint8_int.del(msg.keyUint8); + self.uint8_int8.del(msg.keyUint8); + self.uint8_int42.del(msg.keyUint8); + self.uint8_int256.del(msg.keyUint8); + self.uint8_uint8.del(msg.keyUint8); + self.uint8_uint42.del(msg.keyUint8); + self.uint8_uint256.del(msg.keyUint8); + self.uint8_bool.del(msg.keyUint8); + self.uint8_cell.del(msg.keyUint8); + self.uint8_address.del(msg.keyUint8); + self.uint8_struct.del(msg.keyUint8); + + self.uint42_int.del(msg.keyUint42); + self.uint42_int8.del(msg.keyUint42); + self.uint42_int42.del(msg.keyUint42); + self.uint42_int256.del(msg.keyUint42); + self.uint42_uint8.del(msg.keyUint42); + self.uint42_uint42.del(msg.keyUint42); + self.uint42_uint256.del(msg.keyUint42); + self.uint42_bool.del(msg.keyUint42); + self.uint42_cell.del(msg.keyUint42); + self.uint42_address.del(msg.keyUint42); + self.uint42_struct.del(msg.keyUint42); + + self.uint256_int.del(msg.keyUint256); + self.uint256_int8.del(msg.keyUint256); + self.uint256_int42.del(msg.keyUint256); + self.uint256_int256.del(msg.keyUint256); + self.uint256_uint8.del(msg.keyUint256); + self.uint256_uint42.del(msg.keyUint256); + self.uint256_uint256.del(msg.keyUint256); + self.uint256_bool.del(msg.keyUint256); + self.uint256_cell.del(msg.keyUint256); + self.uint256_address.del(msg.keyUint256); + self.uint256_struct.del(msg.keyUint256); + + // Address Key Maps + self.address_int.del(msg.keyAddress); + self.address_int8.del(msg.keyAddress); + self.address_int42.del(msg.keyAddress); + self.address_int256.del(msg.keyAddress); + self.address_uint8.del(msg.keyAddress); + self.address_uint42.del(msg.keyAddress); + self.address_uint256.del(msg.keyAddress); + self.address_bool.del(msg.keyAddress); + self.address_cell.del(msg.keyAddress); + self.address_address.del(msg.keyAddress); + self.address_struct.del(msg.keyAddress); + } + + receive(msg: ReplaceAllMaps) { + // Integer Key Maps + self.int_int.replace(msg.keyInt, msg.valueInt); + self.int_int8.replace(msg.keyInt, msg.valueInt8); + self.int_int42.replace(msg.keyInt, msg.valueInt42); + self.int_int256.replace(msg.keyInt, msg.valueInt256); + self.int_uint8.replace(msg.keyInt, msg.valueUint8); + self.int_uint42.replace(msg.keyInt, msg.valueUint42); + self.int_uint256.replace(msg.keyInt, msg.valueUint256); + self.int_bool.replace(msg.keyInt, msg.valueBool); + self.int_cell.replace(msg.keyInt, msg.valueCell); + self.int_address.replace(msg.keyInt, msg.valueAddress); + self.int_struct.replace(msg.keyInt, msg.valueStruct); + + self.int8_int.replace(msg.keyInt8, msg.valueInt); + self.int8_int8.replace(msg.keyInt8, msg.valueInt8); + self.int8_int42.replace(msg.keyInt8, msg.valueInt42); + self.int8_int256.replace(msg.keyInt8, msg.valueInt256); + self.int8_uint8.replace(msg.keyInt8, msg.valueUint8); + self.int8_uint42.replace(msg.keyInt8, msg.valueUint42); + self.int8_uint256.replace(msg.keyInt8, msg.valueUint256); + self.int8_bool.replace(msg.keyInt8, msg.valueBool); + self.int8_cell.replace(msg.keyInt8, msg.valueCell); + self.int8_address.replace(msg.keyInt8, msg.valueAddress); + self.int8_struct.replace(msg.keyInt8, msg.valueStruct); + + self.int42_int.replace(msg.keyInt42, msg.valueInt); + self.int42_int8.replace(msg.keyInt42, msg.valueInt8); + self.int42_int42.replace(msg.keyInt42, msg.valueInt42); + self.int42_int256.replace(msg.keyInt42, msg.valueInt256); + self.int42_uint8.replace(msg.keyInt42, msg.valueUint8); + self.int42_uint42.replace(msg.keyInt42, msg.valueUint42); + self.int42_uint256.replace(msg.keyInt42, msg.valueUint256); + self.int42_bool.replace(msg.keyInt42, msg.valueBool); + self.int42_cell.replace(msg.keyInt42, msg.valueCell); + self.int42_address.replace(msg.keyInt42, msg.valueAddress); + self.int42_struct.replace(msg.keyInt42, msg.valueStruct); + + self.int256_int.replace(msg.keyInt256, msg.valueInt); + self.int256_int8.replace(msg.keyInt256, msg.valueInt8); + self.int256_int42.replace(msg.keyInt256, msg.valueInt42); + self.int256_int256.replace(msg.keyInt256, msg.valueInt256); + self.int256_uint8.replace(msg.keyInt256, msg.valueUint8); + self.int256_uint42.replace(msg.keyInt256, msg.valueUint42); + self.int256_uint256.replace(msg.keyInt256, msg.valueUint256); + self.int256_bool.replace(msg.keyInt256, msg.valueBool); + self.int256_cell.replace(msg.keyInt256, msg.valueCell); + self.int256_address.replace(msg.keyInt256, msg.valueAddress); + self.int256_struct.replace(msg.keyInt256, msg.valueStruct); + + self.uint8_int.replace(msg.keyUint8, msg.valueInt); + self.uint8_int8.replace(msg.keyUint8, msg.valueInt8); + self.uint8_int42.replace(msg.keyUint8, msg.valueInt42); + self.uint8_int256.replace(msg.keyUint8, msg.valueInt256); + self.uint8_uint8.replace(msg.keyUint8, msg.valueUint8); + self.uint8_uint42.replace(msg.keyUint8, msg.valueUint42); + self.uint8_uint256.replace(msg.keyUint8, msg.valueUint256); + self.uint8_bool.replace(msg.keyUint8, msg.valueBool); + self.uint8_cell.replace(msg.keyUint8, msg.valueCell); + self.uint8_address.replace(msg.keyUint8, msg.valueAddress); + self.uint8_struct.replace(msg.keyUint8, msg.valueStruct); + + self.uint42_int.replace(msg.keyUint42, msg.valueInt); + self.uint42_int8.replace(msg.keyUint42, msg.valueInt8); + self.uint42_int42.replace(msg.keyUint42, msg.valueInt42); + self.uint42_int256.replace(msg.keyUint42, msg.valueInt256); + self.uint42_uint8.replace(msg.keyUint42, msg.valueUint8); + self.uint42_uint42.replace(msg.keyUint42, msg.valueUint42); + self.uint42_uint256.replace(msg.keyUint42, msg.valueUint256); + self.uint42_bool.replace(msg.keyUint42, msg.valueBool); + self.uint42_cell.replace(msg.keyUint42, msg.valueCell); + self.uint42_address.replace(msg.keyUint42, msg.valueAddress); + self.uint42_struct.replace(msg.keyUint42, msg.valueStruct); + + self.uint256_int.replace(msg.keyUint256, msg.valueInt); + self.uint256_int8.replace(msg.keyUint256, msg.valueInt8); + self.uint256_int42.replace(msg.keyUint256, msg.valueInt42); + self.uint256_int256.replace(msg.keyUint256, msg.valueInt256); + self.uint256_uint8.replace(msg.keyUint256, msg.valueUint8); + self.uint256_uint42.replace(msg.keyUint256, msg.valueUint42); + self.uint256_uint256.replace(msg.keyUint256, msg.valueUint256); + self.uint256_bool.replace(msg.keyUint256, msg.valueBool); + self.uint256_cell.replace(msg.keyUint256, msg.valueCell); + self.uint256_address.replace(msg.keyUint256, msg.valueAddress); + self.uint256_struct.replace(msg.keyUint256, msg.valueStruct); + + // Address Key Maps + self.address_int.replace(msg.keyAddress, msg.valueInt); + self.address_int8.replace(msg.keyAddress, msg.valueInt8); + self.address_int42.replace(msg.keyAddress, msg.valueInt42); + self.address_int256.replace(msg.keyAddress, msg.valueInt256); + self.address_uint8.replace(msg.keyAddress, msg.valueUint8); + self.address_uint42.replace(msg.keyAddress, msg.valueUint42); + self.address_uint256.replace(msg.keyAddress, msg.valueUint256); + self.address_bool.replace(msg.keyAddress, msg.valueBool); + self.address_cell.replace(msg.keyAddress, msg.valueCell); + self.address_address.replace(msg.keyAddress, msg.valueAddress); + self.address_struct.replace(msg.keyAddress, msg.valueStruct); + } + + receive(msg: ReplaceGetAllMaps) { + // Integer Key Maps + self.int_int.replaceGet(msg.keyInt, msg.valueInt); + self.int_int8.replaceGet(msg.keyInt, msg.valueInt8); + self.int_int42.replaceGet(msg.keyInt, msg.valueInt42); + self.int_int256.replaceGet(msg.keyInt, msg.valueInt256); + self.int_uint8.replaceGet(msg.keyInt, msg.valueUint8); + self.int_uint42.replaceGet(msg.keyInt, msg.valueUint42); + self.int_uint256.replaceGet(msg.keyInt, msg.valueUint256); + self.int_bool.replaceGet(msg.keyInt, msg.valueBool); + self.int_cell.replaceGet(msg.keyInt, msg.valueCell); + self.int_address.replaceGet(msg.keyInt, msg.valueAddress); + self.int_struct.replaceGet(msg.keyInt, msg.valueStruct); + + self.int8_int.replaceGet(msg.keyInt8, msg.valueInt); + self.int8_int8.replaceGet(msg.keyInt8, msg.valueInt8); + self.int8_int42.replaceGet(msg.keyInt8, msg.valueInt42); + self.int8_int256.replaceGet(msg.keyInt8, msg.valueInt256); + self.int8_uint8.replaceGet(msg.keyInt8, msg.valueUint8); + self.int8_uint42.replaceGet(msg.keyInt8, msg.valueUint42); + self.int8_uint256.replaceGet(msg.keyInt8, msg.valueUint256); + self.int8_bool.replaceGet(msg.keyInt8, msg.valueBool); + self.int8_cell.replaceGet(msg.keyInt8, msg.valueCell); + self.int8_address.replaceGet(msg.keyInt8, msg.valueAddress); + self.int8_struct.replaceGet(msg.keyInt8, msg.valueStruct); + + self.int42_int.replaceGet(msg.keyInt42, msg.valueInt); + self.int42_int8.replaceGet(msg.keyInt42, msg.valueInt8); + self.int42_int42.replaceGet(msg.keyInt42, msg.valueInt42); + self.int42_int256.replaceGet(msg.keyInt42, msg.valueInt256); + self.int42_uint8.replaceGet(msg.keyInt42, msg.valueUint8); + self.int42_uint42.replaceGet(msg.keyInt42, msg.valueUint42); + self.int42_uint256.replaceGet(msg.keyInt42, msg.valueUint256); + self.int42_bool.replaceGet(msg.keyInt42, msg.valueBool); + self.int42_cell.replaceGet(msg.keyInt42, msg.valueCell); + self.int42_address.replaceGet(msg.keyInt42, msg.valueAddress); + self.int42_struct.replaceGet(msg.keyInt42, msg.valueStruct); + + self.int256_int.replaceGet(msg.keyInt256, msg.valueInt); + self.int256_int8.replaceGet(msg.keyInt256, msg.valueInt8); + self.int256_int42.replaceGet(msg.keyInt256, msg.valueInt42); + self.int256_int256.replaceGet(msg.keyInt256, msg.valueInt256); + self.int256_uint8.replaceGet(msg.keyInt256, msg.valueUint8); + self.int256_uint42.replaceGet(msg.keyInt256, msg.valueUint42); + self.int256_uint256.replaceGet(msg.keyInt256, msg.valueUint256); + self.int256_bool.replaceGet(msg.keyInt256, msg.valueBool); + self.int256_cell.replaceGet(msg.keyInt256, msg.valueCell); + self.int256_address.replaceGet(msg.keyInt256, msg.valueAddress); + self.int256_struct.replaceGet(msg.keyInt256, msg.valueStruct); + + self.uint8_int.replaceGet(msg.keyUint8, msg.valueInt); + self.uint8_int8.replaceGet(msg.keyUint8, msg.valueInt8); + self.uint8_int42.replaceGet(msg.keyUint8, msg.valueInt42); + self.uint8_int256.replaceGet(msg.keyUint8, msg.valueInt256); + self.uint8_uint8.replaceGet(msg.keyUint8, msg.valueUint8); + self.uint8_uint42.replaceGet(msg.keyUint8, msg.valueUint42); + self.uint8_uint256.replaceGet(msg.keyUint8, msg.valueUint256); + self.uint8_bool.replaceGet(msg.keyUint8, msg.valueBool); + self.uint8_cell.replaceGet(msg.keyUint8, msg.valueCell); + self.uint8_address.replaceGet(msg.keyUint8, msg.valueAddress); + self.uint8_struct.replaceGet(msg.keyUint8, msg.valueStruct); + + self.uint42_int.replaceGet(msg.keyUint42, msg.valueInt); + self.uint42_int8.replaceGet(msg.keyUint42, msg.valueInt8); + self.uint42_int42.replaceGet(msg.keyUint42, msg.valueInt42); + self.uint42_int256.replaceGet(msg.keyUint42, msg.valueInt256); + self.uint42_uint8.replaceGet(msg.keyUint42, msg.valueUint8); + self.uint42_uint42.replaceGet(msg.keyUint42, msg.valueUint42); + self.uint42_uint256.replaceGet(msg.keyUint42, msg.valueUint256); + self.uint42_bool.replaceGet(msg.keyUint42, msg.valueBool); + self.uint42_cell.replaceGet(msg.keyUint42, msg.valueCell); + self.uint42_address.replaceGet(msg.keyUint42, msg.valueAddress); + self.uint42_struct.replaceGet(msg.keyUint42, msg.valueStruct); + + self.uint256_int.replaceGet(msg.keyUint256, msg.valueInt); + self.uint256_int8.replaceGet(msg.keyUint256, msg.valueInt8); + self.uint256_int42.replaceGet(msg.keyUint256, msg.valueInt42); + self.uint256_int256.replaceGet(msg.keyUint256, msg.valueInt256); + self.uint256_uint8.replaceGet(msg.keyUint256, msg.valueUint8); + self.uint256_uint42.replaceGet(msg.keyUint256, msg.valueUint42); + self.uint256_uint256.replaceGet(msg.keyUint256, msg.valueUint256); + self.uint256_bool.replaceGet(msg.keyUint256, msg.valueBool); + self.uint256_cell.replaceGet(msg.keyUint256, msg.valueCell); + self.uint256_address.replaceGet(msg.keyUint256, msg.valueAddress); + self.uint256_struct.replaceGet(msg.keyUint256, msg.valueStruct); + + // Address Key Maps + self.address_int.replaceGet(msg.keyAddress, msg.valueInt); + self.address_int8.replaceGet(msg.keyAddress, msg.valueInt8); + self.address_int42.replaceGet(msg.keyAddress, msg.valueInt42); + self.address_int256.replaceGet(msg.keyAddress, msg.valueInt256); + self.address_uint8.replaceGet(msg.keyAddress, msg.valueUint8); + self.address_uint42.replaceGet(msg.keyAddress, msg.valueUint42); + self.address_uint256.replaceGet(msg.keyAddress, msg.valueUint256); + self.address_bool.replaceGet(msg.keyAddress, msg.valueBool); + self.address_cell.replaceGet(msg.keyAddress, msg.valueCell); + self.address_address.replaceGet(msg.keyAddress, msg.valueAddress); + self.address_struct.replaceGet(msg.keyAddress, msg.valueStruct); + } + + // =============================== + // Getters + // =============================== + + get fun allMaps(): MapTestContract { + return self; + } + + get fun getAllMaps( + keyInt: Int, + keyInt8: Int, + keyInt42: Int, + keyInt256: Int, + keyUint8: Int, + keyUint42: Int, + keyUint256: Int, + keyAddress: Address + ): GetAllMapsResult { + return GetAllMapsResult { + // Integer Key Maps + int_int: self.int_int.get(keyInt), + int_int8: self.int_int8.get(keyInt), + int_int42: self.int_int42.get(keyInt), + int_int256: self.int_int256.get(keyInt), + int_uint8: self.int_uint8.get(keyInt), + int_uint42: self.int_uint42.get(keyInt), + int_uint256: self.int_uint256.get(keyInt), + int_bool: self.int_bool.get(keyInt), + int_cell: self.int_cell.get(keyInt), + int_address: self.int_address.get(keyInt), + int_struct: self.int_struct.get(keyInt), + + int8_int: self.int8_int.get(keyInt8), + int8_int8: self.int8_int8.get(keyInt8), + int8_int42: self.int8_int42.get(keyInt8), + int8_int256: self.int8_int256.get(keyInt8), + int8_uint8: self.int8_uint8.get(keyInt8), + int8_uint42: self.int8_uint42.get(keyInt8), + int8_uint256: self.int8_uint256.get(keyInt8), + int8_bool: self.int8_bool.get(keyInt8), + int8_cell: self.int8_cell.get(keyInt8), + int8_address: self.int8_address.get(keyInt8), + int8_struct: self.int8_struct.get(keyInt8), + + int42_int: self.int42_int.get(keyInt42), + int42_int8: self.int42_int8.get(keyInt42), + int42_int42: self.int42_int42.get(keyInt42), + int42_int256: self.int42_int256.get(keyInt42), + int42_uint8: self.int42_uint8.get(keyInt42), + int42_uint42: self.int42_uint42.get(keyInt42), + int42_uint256: self.int42_uint256.get(keyInt42), + int42_bool: self.int42_bool.get(keyInt42), + int42_cell: self.int42_cell.get(keyInt42), + int42_address: self.int42_address.get(keyInt42), + int42_struct: self.int42_struct.get(keyInt42), + + int256_int: self.int256_int.get(keyInt256), + int256_int8: self.int256_int8.get(keyInt256), + int256_int42: self.int256_int42.get(keyInt256), + int256_int256: self.int256_int256.get(keyInt256), + int256_uint8: self.int256_uint8.get(keyInt256), + int256_uint42: self.int256_uint42.get(keyInt256), + int256_uint256: self.int256_uint256.get(keyInt256), + int256_bool: self.int256_bool.get(keyInt256), + int256_cell: self.int256_cell.get(keyInt256), + int256_address: self.int256_address.get(keyInt256), + int256_struct: self.int256_struct.get(keyInt256), + + uint8_int: self.uint8_int.get(keyUint8), + uint8_int8: self.uint8_int8.get(keyUint8), + uint8_int42: self.uint8_int42.get(keyUint8), + uint8_int256: self.uint8_int256.get(keyUint8), + uint8_uint8: self.uint8_uint8.get(keyUint8), + uint8_uint42: self.uint8_uint42.get(keyUint8), + uint8_uint256: self.uint8_uint256.get(keyUint8), + uint8_bool: self.uint8_bool.get(keyUint8), + uint8_cell: self.uint8_cell.get(keyUint8), + uint8_address: self.uint8_address.get(keyUint8), + uint8_struct: self.uint8_struct.get(keyUint8), + + uint42_int: self.uint42_int.get(keyUint42), + uint42_int8: self.uint42_int8.get(keyUint42), + uint42_int42: self.uint42_int42.get(keyUint42), + uint42_int256: self.uint42_int256.get(keyUint42), + uint42_uint8: self.uint42_uint8.get(keyUint42), + uint42_uint42: self.uint42_uint42.get(keyUint42), + uint42_uint256: self.uint42_uint256.get(keyUint42), + uint42_bool: self.uint42_bool.get(keyUint42), + uint42_cell: self.uint42_cell.get(keyUint42), + uint42_address: self.uint42_address.get(keyUint42), + uint42_struct: self.uint42_struct.get(keyUint42), + + uint256_int: self.uint256_int.get(keyUint256), + uint256_int8: self.uint256_int8.get(keyUint256), + uint256_int42: self.uint256_int42.get(keyUint256), + uint256_int256: self.uint256_int256.get(keyUint256), + uint256_uint8: self.uint256_uint8.get(keyUint256), + uint256_uint42: self.uint256_uint42.get(keyUint256), + uint256_uint256: self.uint256_uint256.get(keyUint256), + uint256_bool: self.uint256_bool.get(keyUint256), + uint256_cell: self.uint256_cell.get(keyUint256), + uint256_address: self.uint256_address.get(keyUint256), + uint256_struct: self.uint256_struct.get(keyUint256), + + // Address Key Maps + address_int: self.address_int.get(keyAddress), + address_int8: self.address_int8.get(keyAddress), + address_int42: self.address_int42.get(keyAddress), + address_int256: self.address_int256.get(keyAddress), + address_uint8: self.address_uint8.get(keyAddress), + address_uint42: self.address_uint42.get(keyAddress), + address_uint256: self.address_uint256.get(keyAddress), + address_bool: self.address_bool.get(keyAddress), + address_cell: self.address_cell.get(keyAddress), + address_address: self.address_address.get(keyAddress), + address_struct: self.address_struct.get(keyAddress) + }; + } + + get fun replaceAllMaps( + keyInt: Int, + keyInt8: Int, + keyInt42: Int, + keyInt256: Int, + keyUint8: Int, + keyUint42: Int, + keyUint256: Int, + keyAddress: Address, + valueInt: Int, + valueInt8: Int, + valueInt42: Int, + valueInt256: Int, + valueUint8: Int, + valueUint42: Int, + valueUint256: Int, + valueBool: Bool, + valueCell: Cell, + valueAddress: Address, + valueStruct: SomeStruct + ): ReplaceAllMapsResult { + return ReplaceAllMapsResult { + // Integer Key Maps + int_int: self.int_int.replace(keyInt, valueInt), + int_int8: self.int_int8.replace(keyInt, valueInt8), + int_int42: self.int_int42.replace(keyInt, valueInt42), + int_int256: self.int_int256.replace(keyInt, valueInt256), + int_uint8: self.int_uint8.replace(keyInt, valueUint8), + int_uint42: self.int_uint42.replace(keyInt, valueUint42), + int_uint256: self.int_uint256.replace(keyInt, valueUint256), + int_bool: self.int_bool.replace(keyInt, valueBool), + int_cell: self.int_cell.replace(keyInt, valueCell), + int_address: self.int_address.replace(keyInt, valueAddress), + int_struct: self.int_struct.replace(keyInt, valueStruct), + + int8_int: self.int8_int.replace(keyInt8, valueInt), + int8_int8: self.int8_int8.replace(keyInt8, valueInt8), + int8_int42: self.int8_int42.replace(keyInt8, valueInt42), + int8_int256: self.int8_int256.replace(keyInt8, valueInt256), + int8_uint8: self.int8_uint8.replace(keyInt8, valueUint8), + int8_uint42: self.int8_uint42.replace(keyInt8, valueUint42), + int8_uint256: self.int8_uint256.replace(keyInt8, valueUint256), + int8_bool: self.int8_bool.replace(keyInt8, valueBool), + int8_cell: self.int8_cell.replace(keyInt8, valueCell), + int8_address: self.int8_address.replace(keyInt8, valueAddress), + int8_struct: self.int8_struct.replace(keyInt8, valueStruct), + + int42_int: self.int42_int.replace(keyInt42, valueInt), + int42_int8: self.int42_int8.replace(keyInt42, valueInt8), + int42_int42: self.int42_int42.replace(keyInt42, valueInt42), + int42_int256: self.int42_int256.replace(keyInt42, valueInt256), + int42_uint8: self.int42_uint8.replace(keyInt42, valueUint8), + int42_uint42: self.int42_uint42.replace(keyInt42, valueUint42), + int42_uint256: self.int42_uint256.replace(keyInt42, valueUint256), + int42_bool: self.int42_bool.replace(keyInt42, valueBool), + int42_cell: self.int42_cell.replace(keyInt42, valueCell), + int42_address: self.int42_address.replace(keyInt42, valueAddress), + int42_struct: self.int42_struct.replace(keyInt42, valueStruct), + + int256_int: self.int256_int.replace(keyInt256, valueInt), + int256_int8: self.int256_int8.replace(keyInt256, valueInt8), + int256_int42: self.int256_int42.replace(keyInt256, valueInt42), + int256_int256: self.int256_int256.replace(keyInt256, valueInt256), + int256_uint8: self.int256_uint8.replace(keyInt256, valueUint8), + int256_uint42: self.int256_uint42.replace(keyInt256, valueUint42), + int256_uint256: self.int256_uint256.replace(keyInt256, valueUint256), + int256_bool: self.int256_bool.replace(keyInt256, valueBool), + int256_cell: self.int256_cell.replace(keyInt256, valueCell), + int256_address: self.int256_address.replace(keyInt256, valueAddress), + int256_struct: self.int256_struct.replace(keyInt256, valueStruct), + + uint8_int: self.uint8_int.replace(keyUint8, valueInt), + uint8_int8: self.uint8_int8.replace(keyUint8, valueInt8), + uint8_int42: self.uint8_int42.replace(keyUint8, valueInt42), + uint8_int256: self.uint8_int256.replace(keyUint8, valueInt256), + uint8_uint8: self.uint8_uint8.replace(keyUint8, valueUint8), + uint8_uint42: self.uint8_uint42.replace(keyUint8, valueUint42), + uint8_uint256: self.uint8_uint256.replace(keyUint8, valueUint256), + uint8_bool: self.uint8_bool.replace(keyUint8, valueBool), + uint8_cell: self.uint8_cell.replace(keyUint8, valueCell), + uint8_address: self.uint8_address.replace(keyUint8, valueAddress), + uint8_struct: self.uint8_struct.replace(keyUint8, valueStruct), + + uint42_int: self.uint42_int.replace(keyUint42, valueInt), + uint42_int8: self.uint42_int8.replace(keyUint42, valueInt8), + uint42_int42: self.uint42_int42.replace(keyUint42, valueInt42), + uint42_int256: self.uint42_int256.replace(keyUint42, valueInt256), + uint42_uint8: self.uint42_uint8.replace(keyUint42, valueUint8), + uint42_uint42: self.uint42_uint42.replace(keyUint42, valueUint42), + uint42_uint256: self.uint42_uint256.replace(keyUint42, valueUint256), + uint42_bool: self.uint42_bool.replace(keyUint42, valueBool), + uint42_cell: self.uint42_cell.replace(keyUint42, valueCell), + uint42_address: self.uint42_address.replace(keyUint42, valueAddress), + uint42_struct: self.uint42_struct.replace(keyUint42, valueStruct), + + uint256_int: self.uint256_int.replace(keyUint256, valueInt), + uint256_int8: self.uint256_int8.replace(keyUint256, valueInt8), + uint256_int42: self.uint256_int42.replace(keyUint256, valueInt42), + uint256_int256: self.uint256_int256.replace(keyUint256, valueInt256), + uint256_uint8: self.uint256_uint8.replace(keyUint256, valueUint8), + uint256_uint42: self.uint256_uint42.replace(keyUint256, valueUint42), + uint256_uint256: self.uint256_uint256.replace(keyUint256, valueUint256), + uint256_bool: self.uint256_bool.replace(keyUint256, valueBool), + uint256_cell: self.uint256_cell.replace(keyUint256, valueCell), + uint256_address: self.uint256_address.replace(keyUint256, valueAddress), + uint256_struct: self.uint256_struct.replace(keyUint256, valueStruct), + + // Address Key Maps + address_int: self.address_int.replace(keyAddress, valueInt), + address_int8: self.address_int8.replace(keyAddress, valueInt8), + address_int42: self.address_int42.replace(keyAddress, valueInt42), + address_int256: self.address_int256.replace(keyAddress, valueInt256), + address_uint8: self.address_uint8.replace(keyAddress, valueUint8), + address_uint42: self.address_uint42.replace(keyAddress, valueUint42), + address_uint256: self.address_uint256.replace(keyAddress, valueUint256), + address_bool: self.address_bool.replace(keyAddress, valueBool), + address_cell: self.address_cell.replace(keyAddress, valueCell), + address_address: self.address_address.replace(keyAddress, valueAddress), + address_struct: self.address_struct.replace(keyAddress, valueStruct) + }; + } + + get fun replaceGetAllMaps( + keyInt: Int, + keyInt8: Int, + keyInt42: Int, + keyInt256: Int, + keyUint8: Int, + keyUint42: Int, + keyUint256: Int, + keyAddress: Address, + valueInt: Int, + valueInt8: Int, + valueInt42: Int, + valueInt256: Int, + valueUint8: Int, + valueUint42: Int, + valueUint256: Int, + valueBool: Bool, + valueCell: Cell, + valueAddress: Address, + valueStruct: SomeStruct + ): ReplaceGetAllMapsResult { + return ReplaceGetAllMapsResult { + // Integer Key Maps + int_int: self.int_int.replaceGet(keyInt, valueInt), + int_int8: self.int_int8.replaceGet(keyInt, valueInt8), + int_int42: self.int_int42.replaceGet(keyInt, valueInt42), + int_int256: self.int_int256.replaceGet(keyInt, valueInt256), + int_uint8: self.int_uint8.replaceGet(keyInt, valueUint8), + int_uint42: self.int_uint42.replaceGet(keyInt, valueUint42), + int_uint256: self.int_uint256.replaceGet(keyInt, valueUint256), + int_bool: self.int_bool.replaceGet(keyInt, valueBool), + int_cell: self.int_cell.replaceGet(keyInt, valueCell), + int_address: self.int_address.replaceGet(keyInt, valueAddress), + int_struct: self.int_struct.replaceGet(keyInt, valueStruct), + + int8_int: self.int8_int.replaceGet(keyInt8, valueInt), + int8_int8: self.int8_int8.replaceGet(keyInt8, valueInt8), + int8_int42: self.int8_int42.replaceGet(keyInt8, valueInt42), + int8_int256: self.int8_int256.replaceGet(keyInt8, valueInt256), + int8_uint8: self.int8_uint8.replaceGet(keyInt8, valueUint8), + int8_uint42: self.int8_uint42.replaceGet(keyInt8, valueUint42), + int8_uint256: self.int8_uint256.replaceGet(keyInt8, valueUint256), + int8_bool: self.int8_bool.replaceGet(keyInt8, valueBool), + int8_cell: self.int8_cell.replaceGet(keyInt8, valueCell), + int8_address: self.int8_address.replaceGet(keyInt8, valueAddress), + int8_struct: self.int8_struct.replaceGet(keyInt8, valueStruct), + + int42_int: self.int42_int.replaceGet(keyInt42, valueInt), + int42_int8: self.int42_int8.replaceGet(keyInt42, valueInt8), + int42_int42: self.int42_int42.replaceGet(keyInt42, valueInt42), + int42_int256: self.int42_int256.replaceGet(keyInt42, valueInt256), + int42_uint8: self.int42_uint8.replaceGet(keyInt42, valueUint8), + int42_uint42: self.int42_uint42.replaceGet(keyInt42, valueUint42), + int42_uint256: self.int42_uint256.replaceGet(keyInt42, valueUint256), + int42_bool: self.int42_bool.replaceGet(keyInt42, valueBool), + int42_cell: self.int42_cell.replaceGet(keyInt42, valueCell), + int42_address: self.int42_address.replaceGet(keyInt42, valueAddress), + int42_struct: self.int42_struct.replaceGet(keyInt42, valueStruct), + + int256_int: self.int256_int.replaceGet(keyInt256, valueInt), + int256_int8: self.int256_int8.replaceGet(keyInt256, valueInt8), + int256_int42: self.int256_int42.replaceGet(keyInt256, valueInt42), + int256_int256: self.int256_int256.replaceGet(keyInt256, valueInt256), + int256_uint8: self.int256_uint8.replaceGet(keyInt256, valueUint8), + int256_uint42: self.int256_uint42.replaceGet(keyInt256, valueUint42), + int256_uint256: self.int256_uint256.replaceGet(keyInt256, valueUint256), + int256_bool: self.int256_bool.replaceGet(keyInt256, valueBool), + int256_cell: self.int256_cell.replaceGet(keyInt256, valueCell), + int256_address: self.int256_address.replaceGet(keyInt256, valueAddress), + int256_struct: self.int256_struct.replaceGet(keyInt256, valueStruct), + + uint8_int: self.uint8_int.replaceGet(keyUint8, valueInt), + uint8_int8: self.uint8_int8.replaceGet(keyUint8, valueInt8), + uint8_int42: self.uint8_int42.replaceGet(keyUint8, valueInt42), + uint8_int256: self.uint8_int256.replaceGet(keyUint8, valueInt256), + uint8_uint8: self.uint8_uint8.replaceGet(keyUint8, valueUint8), + uint8_uint42: self.uint8_uint42.replaceGet(keyUint8, valueUint42), + uint8_uint256: self.uint8_uint256.replaceGet(keyUint8, valueUint256), + uint8_bool: self.uint8_bool.replaceGet(keyUint8, valueBool), + uint8_cell: self.uint8_cell.replaceGet(keyUint8, valueCell), + uint8_address: self.uint8_address.replaceGet(keyUint8, valueAddress), + uint8_struct: self.uint8_struct.replaceGet(keyUint8, valueStruct), + + uint42_int: self.uint42_int.replaceGet(keyUint42, valueInt), + uint42_int8: self.uint42_int8.replaceGet(keyUint42, valueInt8), + uint42_int42: self.uint42_int42.replaceGet(keyUint42, valueInt42), + uint42_int256: self.uint42_int256.replaceGet(keyUint42, valueInt256), + uint42_uint8: self.uint42_uint8.replaceGet(keyUint42, valueUint8), + uint42_uint42: self.uint42_uint42.replaceGet(keyUint42, valueUint42), + uint42_uint256: self.uint42_uint256.replaceGet(keyUint42, valueUint256), + uint42_bool: self.uint42_bool.replaceGet(keyUint42, valueBool), + uint42_cell: self.uint42_cell.replaceGet(keyUint42, valueCell), + uint42_address: self.uint42_address.replaceGet(keyUint42, valueAddress), + uint42_struct: self.uint42_struct.replaceGet(keyUint42, valueStruct), + + uint256_int: self.uint256_int.replaceGet(keyUint256, valueInt), + uint256_int8: self.uint256_int8.replaceGet(keyUint256, valueInt8), + uint256_int42: self.uint256_int42.replaceGet(keyUint256, valueInt42), + uint256_int256: self.uint256_int256.replaceGet(keyUint256, valueInt256), + uint256_uint8: self.uint256_uint8.replaceGet(keyUint256, valueUint8), + uint256_uint42: self.uint256_uint42.replaceGet(keyUint256, valueUint42), + uint256_uint256: self.uint256_uint256.replaceGet(keyUint256, valueUint256), + uint256_bool: self.uint256_bool.replaceGet(keyUint256, valueBool), + uint256_cell: self.uint256_cell.replaceGet(keyUint256, valueCell), + uint256_address: self.uint256_address.replaceGet(keyUint256, valueAddress), + uint256_struct: self.uint256_struct.replaceGet(keyUint256, valueStruct), + + // Address Key Maps + address_int: self.address_int.replaceGet(keyAddress, valueInt), + address_int8: self.address_int8.replaceGet(keyAddress, valueInt8), + address_int42: self.address_int42.replaceGet(keyAddress, valueInt42), + address_int256: self.address_int256.replaceGet(keyAddress, valueInt256), + address_uint8: self.address_uint8.replaceGet(keyAddress, valueUint8), + address_uint42: self.address_uint42.replaceGet(keyAddress, valueUint42), + address_uint256: self.address_uint256.replaceGet(keyAddress, valueUint256), + address_bool: self.address_bool.replaceGet(keyAddress, valueBool), + address_cell: self.address_cell.replaceGet(keyAddress, valueCell), + address_address: self.address_address.replaceGet(keyAddress, valueAddress), + address_struct: self.address_struct.replaceGet(keyAddress, valueStruct) + }; + } + + get fun existsAllMaps( + keyInt: Int, + keyInt8: Int, + keyInt42: Int, + keyInt256: Int, + keyUint8: Int, + keyUint42: Int, + keyUint256: Int, + keyAddress: Address + ): ExistsAllMapsResult { + return ExistsAllMapsResult { + // Integer Key Maps + int_int: self.int_int.exists(keyInt), + int_int8: self.int_int8.exists(keyInt), + int_int42: self.int_int42.exists(keyInt), + int_int256: self.int_int256.exists(keyInt), + int_uint8: self.int_uint8.exists(keyInt), + int_uint42: self.int_uint42.exists(keyInt), + int_uint256: self.int_uint256.exists(keyInt), + int_bool: self.int_bool.exists(keyInt), + int_cell: self.int_cell.exists(keyInt), + int_address: self.int_address.exists(keyInt), + int_struct: self.int_struct.exists(keyInt), + + int8_int: self.int8_int.exists(keyInt8), + int8_int8: self.int8_int8.exists(keyInt8), + int8_int42: self.int8_int42.exists(keyInt8), + int8_int256: self.int8_int256.exists(keyInt8), + int8_uint8: self.int8_uint8.exists(keyInt8), + int8_uint42: self.int8_uint42.exists(keyInt8), + int8_uint256: self.int8_uint256.exists(keyInt8), + int8_bool: self.int8_bool.exists(keyInt8), + int8_cell: self.int8_cell.exists(keyInt8), + int8_address: self.int8_address.exists(keyInt8), + int8_struct: self.int8_struct.exists(keyInt8), + + int42_int: self.int42_int.exists(keyInt42), + int42_int8: self.int42_int8.exists(keyInt42), + int42_int42: self.int42_int42.exists(keyInt42), + int42_int256: self.int42_int256.exists(keyInt42), + int42_uint8: self.int42_uint8.exists(keyInt42), + int42_uint42: self.int42_uint42.exists(keyInt42), + int42_uint256: self.int42_uint256.exists(keyInt42), + int42_bool: self.int42_bool.exists(keyInt42), + int42_cell: self.int42_cell.exists(keyInt42), + int42_address: self.int42_address.exists(keyInt42), + int42_struct: self.int42_struct.exists(keyInt42), + + int256_int: self.int256_int.exists(keyInt256), + int256_int8: self.int256_int8.exists(keyInt256), + int256_int42: self.int256_int42.exists(keyInt256), + int256_int256: self.int256_int256.exists(keyInt256), + int256_uint8: self.int256_uint8.exists(keyInt256), + int256_uint42: self.int256_uint42.exists(keyInt256), + int256_uint256: self.int256_uint256.exists(keyInt256), + int256_bool: self.int256_bool.exists(keyInt256), + int256_cell: self.int256_cell.exists(keyInt256), + int256_address: self.int256_address.exists(keyInt256), + int256_struct: self.int256_struct.exists(keyInt256), + + uint8_int: self.uint8_int.exists(keyUint8), + uint8_int8: self.uint8_int8.exists(keyUint8), + uint8_int42: self.uint8_int42.exists(keyUint8), + uint8_int256: self.uint8_int256.exists(keyUint8), + uint8_uint8: self.uint8_uint8.exists(keyUint8), + uint8_uint42: self.uint8_uint42.exists(keyUint8), + uint8_uint256: self.uint8_uint256.exists(keyUint8), + uint8_bool: self.uint8_bool.exists(keyUint8), + uint8_cell: self.uint8_cell.exists(keyUint8), + uint8_address: self.uint8_address.exists(keyUint8), + uint8_struct: self.uint8_struct.exists(keyUint8), + + uint42_int: self.uint42_int.exists(keyUint42), + uint42_int8: self.uint42_int8.exists(keyUint42), + uint42_int42: self.uint42_int42.exists(keyUint42), + uint42_int256: self.uint42_int256.exists(keyUint42), + uint42_uint8: self.uint42_uint8.exists(keyUint42), + uint42_uint42: self.uint42_uint42.exists(keyUint42), + uint42_uint256: self.uint42_uint256.exists(keyUint42), + uint42_bool: self.uint42_bool.exists(keyUint42), + uint42_cell: self.uint42_cell.exists(keyUint42), + uint42_address: self.uint42_address.exists(keyUint42), + uint42_struct: self.uint42_struct.exists(keyUint42), + + uint256_int: self.uint256_int.exists(keyUint256), + uint256_int8: self.uint256_int8.exists(keyUint256), + uint256_int42: self.uint256_int42.exists(keyUint256), + uint256_int256: self.uint256_int256.exists(keyUint256), + uint256_uint8: self.uint256_uint8.exists(keyUint256), + uint256_uint42: self.uint256_uint42.exists(keyUint256), + uint256_uint256: self.uint256_uint256.exists(keyUint256), + uint256_bool: self.uint256_bool.exists(keyUint256), + uint256_cell: self.uint256_cell.exists(keyUint256), + uint256_address: self.uint256_address.exists(keyUint256), + uint256_struct: self.uint256_struct.exists(keyUint256), + + // Address Key Maps + address_int: self.address_int.exists(keyAddress), + address_int8: self.address_int8.exists(keyAddress), + address_int42: self.address_int42.exists(keyAddress), + address_int256: self.address_int256.exists(keyAddress), + address_uint8: self.address_uint8.exists(keyAddress), + address_uint42: self.address_uint42.exists(keyAddress), + address_uint256: self.address_uint256.exists(keyAddress), + address_bool: self.address_bool.exists(keyAddress), + address_cell: self.address_cell.exists(keyAddress), + address_address: self.address_address.exists(keyAddress), + address_struct: self.address_struct.exists(keyAddress) + }; + } + + get fun isEmptyAllMaps(): IsEmptyAllMapsResult { + return IsEmptyAllMapsResult { + // Integer Key Maps + int_int: self.int_int.isEmpty(), + int_int8: self.int_int8.isEmpty(), + int_int42: self.int_int42.isEmpty(), + int_int256: self.int_int256.isEmpty(), + int_uint8: self.int_uint8.isEmpty(), + int_uint42: self.int_uint42.isEmpty(), + int_uint256: self.int_uint256.isEmpty(), + int_bool: self.int_bool.isEmpty(), + int_cell: self.int_cell.isEmpty(), + int_address: self.int_address.isEmpty(), + int_struct: self.int_struct.isEmpty(), + + int8_int: self.int8_int.isEmpty(), + int8_int8: self.int8_int8.isEmpty(), + int8_int42: self.int8_int42.isEmpty(), + int8_int256: self.int8_int256.isEmpty(), + int8_uint8: self.int8_uint8.isEmpty(), + int8_uint42: self.int8_uint42.isEmpty(), + int8_uint256: self.int8_uint256.isEmpty(), + int8_bool: self.int8_bool.isEmpty(), + int8_cell: self.int8_cell.isEmpty(), + int8_address: self.int8_address.isEmpty(), + int8_struct: self.int8_struct.isEmpty(), + + int42_int: self.int42_int.isEmpty(), + int42_int8: self.int42_int8.isEmpty(), + int42_int42: self.int42_int42.isEmpty(), + int42_int256: self.int42_int256.isEmpty(), + int42_uint8: self.int42_uint8.isEmpty(), + int42_uint42: self.int42_uint42.isEmpty(), + int42_uint256: self.int42_uint256.isEmpty(), + int42_bool: self.int42_bool.isEmpty(), + int42_cell: self.int42_cell.isEmpty(), + int42_address: self.int42_address.isEmpty(), + int42_struct: self.int42_struct.isEmpty(), + + int256_int: self.int256_int.isEmpty(), + int256_int8: self.int256_int8.isEmpty(), + int256_int42: self.int256_int42.isEmpty(), + int256_int256: self.int256_int256.isEmpty(), + int256_uint8: self.int256_uint8.isEmpty(), + int256_uint42: self.int256_uint42.isEmpty(), + int256_uint256: self.int256_uint256.isEmpty(), + int256_bool: self.int256_bool.isEmpty(), + int256_cell: self.int256_cell.isEmpty(), + int256_address: self.int256_address.isEmpty(), + int256_struct: self.int256_struct.isEmpty(), + + uint8_int: self.uint8_int.isEmpty(), + uint8_int8: self.uint8_int8.isEmpty(), + uint8_int42: self.uint8_int42.isEmpty(), + uint8_int256: self.uint8_int256.isEmpty(), + uint8_uint8: self.uint8_uint8.isEmpty(), + uint8_uint42: self.uint8_uint42.isEmpty(), + uint8_uint256: self.uint8_uint256.isEmpty(), + uint8_bool: self.uint8_bool.isEmpty(), + uint8_cell: self.uint8_cell.isEmpty(), + uint8_address: self.uint8_address.isEmpty(), + uint8_struct: self.uint8_struct.isEmpty(), + + uint42_int: self.uint42_int.isEmpty(), + uint42_int8: self.uint42_int8.isEmpty(), + uint42_int42: self.uint42_int42.isEmpty(), + uint42_int256: self.uint42_int256.isEmpty(), + uint42_uint8: self.uint42_uint8.isEmpty(), + uint42_uint42: self.uint42_uint42.isEmpty(), + uint42_uint256: self.uint42_uint256.isEmpty(), + uint42_bool: self.uint42_bool.isEmpty(), + uint42_cell: self.uint42_cell.isEmpty(), + uint42_address: self.uint42_address.isEmpty(), + uint42_struct: self.uint42_struct.isEmpty(), + + uint256_int: self.uint256_int.isEmpty(), + uint256_int8: self.uint256_int8.isEmpty(), + uint256_int42: self.uint256_int42.isEmpty(), + uint256_int256: self.uint256_int256.isEmpty(), + uint256_uint8: self.uint256_uint8.isEmpty(), + uint256_uint42: self.uint256_uint42.isEmpty(), + uint256_uint256: self.uint256_uint256.isEmpty(), + uint256_bool: self.uint256_bool.isEmpty(), + uint256_cell: self.uint256_cell.isEmpty(), + uint256_address: self.uint256_address.isEmpty(), + uint256_struct: self.uint256_struct.isEmpty(), + + // Address Key Maps + address_int: self.address_int.isEmpty(), + address_int8: self.address_int8.isEmpty(), + address_int42: self.address_int42.isEmpty(), + address_int256: self.address_int256.isEmpty(), + address_uint8: self.address_uint8.isEmpty(), + address_uint42: self.address_uint42.isEmpty(), + address_uint256: self.address_uint256.isEmpty(), + address_bool: self.address_bool.isEmpty(), + address_cell: self.address_cell.isEmpty(), + address_address: self.address_address.isEmpty(), + address_struct: self.address_struct.isEmpty() + }; + } + + get fun asCellAllMaps(): AsCellAllMapsResult { + return AsCellAllMapsResult { + // Integer Key Maps + int_int: self.int_int.asCell(), + int_int8: self.int_int8.asCell(), + int_int42: self.int_int42.asCell(), + int_int256: self.int_int256.asCell(), + int_uint8: self.int_uint8.asCell(), + int_uint42: self.int_uint42.asCell(), + int_uint256: self.int_uint256.asCell(), + int_bool: self.int_bool.asCell(), + int_cell: self.int_cell.asCell(), + int_address: self.int_address.asCell(), + int_struct: self.int_struct.asCell(), + + int8_int: self.int8_int.asCell(), + int8_int8: self.int8_int8.asCell(), + int8_int42: self.int8_int42.asCell(), + int8_int256: self.int8_int256.asCell(), + int8_uint8: self.int8_uint8.asCell(), + int8_uint42: self.int8_uint42.asCell(), + int8_uint256: self.int8_uint256.asCell(), + int8_bool: self.int8_bool.asCell(), + int8_cell: self.int8_cell.asCell(), + int8_address: self.int8_address.asCell(), + int8_struct: self.int8_struct.asCell(), + + int42_int: self.int42_int.asCell(), + int42_int8: self.int42_int8.asCell(), + int42_int42: self.int42_int42.asCell(), + int42_int256: self.int42_int256.asCell(), + int42_uint8: self.int42_uint8.asCell(), + int42_uint42: self.int42_uint42.asCell(), + int42_uint256: self.int42_uint256.asCell(), + int42_bool: self.int42_bool.asCell(), + int42_cell: self.int42_cell.asCell(), + int42_address: self.int42_address.asCell(), + int42_struct: self.int42_struct.asCell(), + + int256_int: self.int256_int.asCell(), + int256_int8: self.int256_int8.asCell(), + int256_int42: self.int256_int42.asCell(), + int256_int256: self.int256_int256.asCell(), + int256_uint8: self.int256_uint8.asCell(), + int256_uint42: self.int256_uint42.asCell(), + int256_uint256: self.int256_uint256.asCell(), + int256_bool: self.int256_bool.asCell(), + int256_cell: self.int256_cell.asCell(), + int256_address: self.int256_address.asCell(), + int256_struct: self.int256_struct.asCell(), + + uint8_int: self.uint8_int.asCell(), + uint8_int8: self.uint8_int8.asCell(), + uint8_int42: self.uint8_int42.asCell(), + uint8_int256: self.uint8_int256.asCell(), + uint8_uint8: self.uint8_uint8.asCell(), + uint8_uint42: self.uint8_uint42.asCell(), + uint8_uint256: self.uint8_uint256.asCell(), + uint8_bool: self.uint8_bool.asCell(), + uint8_cell: self.uint8_cell.asCell(), + uint8_address: self.uint8_address.asCell(), + uint8_struct: self.uint8_struct.asCell(), + + uint42_int: self.uint42_int.asCell(), + uint42_int8: self.uint42_int8.asCell(), + uint42_int42: self.uint42_int42.asCell(), + uint42_int256: self.uint42_int256.asCell(), + uint42_uint8: self.uint42_uint8.asCell(), + uint42_uint42: self.uint42_uint42.asCell(), + uint42_uint256: self.uint42_uint256.asCell(), + uint42_bool: self.uint42_bool.asCell(), + uint42_cell: self.uint42_cell.asCell(), + uint42_address: self.uint42_address.asCell(), + uint42_struct: self.uint42_struct.asCell(), + + uint256_int: self.uint256_int.asCell(), + uint256_int8: self.uint256_int8.asCell(), + uint256_int42: self.uint256_int42.asCell(), + uint256_int256: self.uint256_int256.asCell(), + uint256_uint8: self.uint256_uint8.asCell(), + uint256_uint42: self.uint256_uint42.asCell(), + uint256_uint256: self.uint256_uint256.asCell(), + uint256_bool: self.uint256_bool.asCell(), + uint256_cell: self.uint256_cell.asCell(), + uint256_address: self.uint256_address.asCell(), + uint256_struct: self.uint256_struct.asCell(), + + // Address Key Maps + address_int: self.address_int.asCell(), + address_int8: self.address_int8.asCell(), + address_int42: self.address_int42.asCell(), + address_int256: self.address_int256.asCell(), + address_uint8: self.address_uint8.asCell(), + address_uint42: self.address_uint42.asCell(), + address_uint256: self.address_uint256.asCell(), + address_bool: self.address_bool.asCell(), + address_cell: self.address_cell.asCell(), + address_address: self.address_address.asCell(), + address_struct: self.address_struct.asCell() + }; } // - // Int Maps + // Edge Cases // - intMap1: map; - intMap2: map; - intMap3: map; - intMap4: map; - intMap5: map; - intMap6_1: map; - intMap6_2: map; - intMap6_3: map; - intMap6_4: map; - intMap6_5: map; - intMap6_6: map; - intMap6_7: map; - - intMap7_1: map; - intMap7_2: map; - intMap7_3: map; - intMap7_4: map; - intMap7_5: map; - intMap7_6: map; - - intMap8_1: map; - intMap8_2: map; - intMap8_3: map; - intMap8_4: map; - intMap8_5: map; - intMap8_6: map; - intMap8_7: map; - - intMap9_1: map; - intMap9_2: map; - intMap9_3: map; - intMap9_4: map; - intMap9_5: map; - intMap9_6: map; - - intMap10_1: map; - intMap10_2: map; - intMap10_3: map; - intMap10_4: map; - - receive(msg: SetIntMap1) { - self.intMap1.set(msg.key, msg.value); - } - - receive(msg: SetIntMap2) { - self.intMap2.set(msg.key, msg.value); - } - - receive(msg: SetIntMap3) { - self.intMap3.set(msg.key, msg.value); - } - - receive(msg: SetIntMap4) { - self.intMap4.set(msg.key, msg.value); - } - - receive(msg: SetIntMap5) { - self.intMap5.set(msg.key, msg.value); - } - - receive(msg: SetIntMap6) { - self.intMap6_1.set(msg.key, msg.value); - self.intMap6_2.set(msg.key, msg.value); - self.intMap6_3.set(msg.key, msg.value); - self.intMap6_4.set(msg.key, msg.value); - self.intMap6_5.set(msg.key, msg.value); - self.intMap6_6.set(msg.key, msg.value); - self.intMap6_7.set(msg.key, msg.value); - } - - receive(msg: SetUIntMap7) { - self.intMap7_1.set(msg.key, msg.value); - self.intMap7_2.set(msg.key, msg.value); - self.intMap7_3.set(msg.key, msg.value); - self.intMap7_4.set(msg.key, msg.value); - self.intMap7_5.set(msg.key, msg.value); - self.intMap7_6.set(msg.key, msg.value); - } - - receive(msg: SetIntMap8) { - self.intMap8_1.set(msg.key, msg.value); - self.intMap8_2.set(msg.key, msg.value); - self.intMap8_3.set(msg.key, msg.value); - self.intMap8_4.set(msg.key, msg.value); - self.intMap8_5.set(msg.key, msg.value); - self.intMap8_6.set(msg.key, msg.value); - self.intMap8_7.set(msg.key, msg.value); - } - - receive(msg: SetUIntMap9) { - self.intMap9_1.set(msg.key, msg.value); - self.intMap9_2.set(msg.key, msg.value); - self.intMap9_3.set(msg.key, msg.value); - self.intMap9_4.set(msg.key, msg.value); - self.intMap9_5.set(msg.key, msg.value); - self.intMap9_6.set(msg.key, msg.value); - } - - receive(msg: SetUIntMap10) { - self.intMap10_1.set(msg.key, msg.value); - self.intMap10_2.set(msg.key, msg.value); - self.intMap10_3.set(msg.key, msg.value); - self.intMap10_4.set(msg.key, msg.value); - } - - receive(msg: DelIntMap1) { - self.intMap1.del(msg.key); - } - - receive(msg: DelIntMap2) { - self.intMap2.del(msg.key); - } - - receive(msg: DelIntMap3) { - self.intMap3.del(msg.key); - } - - receive(msg: DelIntMap4) { - self.intMap4.del(msg.key); - } - - receive(msg: DelIntMap5) { - self.intMap5.del(msg.key); - } - - receive(msg: DelIntMap6) { - self.intMap6_1.del(msg.key); - self.intMap6_2.del(msg.key); - self.intMap6_3.del(msg.key); - self.intMap6_4.del(msg.key); - self.intMap6_5.del(msg.key); - self.intMap6_6.del(msg.key); - self.intMap6_6.del(msg.key); - self.intMap6_7.del(msg.key); - } - - receive(msg: DelUIntMap7) { - self.intMap7_1.del(msg.key); - self.intMap7_2.del(msg.key); - self.intMap7_3.del(msg.key); - self.intMap7_4.del(msg.key); - self.intMap7_5.del(msg.key); - self.intMap7_6.del(msg.key); - } - - receive(msg: DelIntMap8) { - self.intMap8_1.del(msg.key); - self.intMap8_2.del(msg.key); - self.intMap8_3.del(msg.key); - self.intMap8_4.del(msg.key); - self.intMap8_5.del(msg.key); - self.intMap8_6.del(msg.key); - self.intMap8_7.del(msg.key); - } - - receive(msg: DelUIntMap9) { - self.intMap9_1.del(msg.key); - self.intMap9_2.del(msg.key); - self.intMap9_3.del(msg.key); - self.intMap9_4.del(msg.key); - self.intMap9_5.del(msg.key); - self.intMap9_6.del(msg.key); - } - - receive(msg: DelUIntMap10) { - self.intMap10_1.del(msg.key); - self.intMap10_2.del(msg.key); - self.intMap10_3.del(msg.key); - self.intMap10_4.del(msg.key); - } - - get fun intMap1(): map { - return self.intMap1; - } - - get fun intMap1Value(key: Int): Int? { - return self.intMap1.get(key); - } - - get fun intMap2(): map { - return self.intMap2; - } - - get fun intMap2Value(key: Int): Bool? { - return self.intMap2.get(key); - } - - get fun intMap3(): map { - return self.intMap3; - } - - get fun intMap3Value(key: Int): Cell? { - return self.intMap3.get(key); - } - - get fun intMap4(): map { - return self.intMap4; - } - - get fun intMap4Value(key: Int): SomeStruct? { - return self.intMap4.get(key); - } - - get fun intMap5(): map { - return self.intMap5; - } - - get fun intMap5Value(key: Int): Address? { - return self.intMap5.get(key); - } - - get fun intMap6_1(): map { - return self.intMap6_1; - } - - get fun intMap6_1Value(key: Int): Int? { - return self.intMap6_1.get(key); - } - - get fun intMap6_2(): map { - return self.intMap6_2; - } - - get fun intMap6_2Value(key: Int): Int? { - return self.intMap6_2.get(key); - } - - get fun intMap6_3(): map { - return self.intMap6_3; - } - - get fun intMap6_3Value(key: Int): Int? { - return self.intMap6_3.get(key); - } - - get fun intMap6_4(): map { - return self.intMap6_4; - } - - get fun intMap6_4Value(key: Int): Int? { - return self.intMap6_4.get(key); - } - - get fun intMap6_5(): map { - return self.intMap6_5; - } - - get fun intMap6_5Value(key: Int): Int? { - return self.intMap6_5.get(key); - } - - get fun intMap6_6(): map { - return self.intMap6_6; - } - - get fun intMap6_6Value(key: Int): Int? { - return self.intMap6_6.get(key); - } - - get fun intMap6_7(): map { - return self.intMap6_7; - } - - get fun intMap6_7Value(key: Int): Int? { - return self.intMap6_7.get(key); - } - - get fun intMap7_1(): map { - return self.intMap7_1; - } - - get fun intMap7_1Value(key: Int): Int? { - return self.intMap7_1.get(key); - } - - get fun intMap7_2(): map { - return self.intMap7_2; - } - - get fun intMap7_2Value(key: Int): Int? { - return self.intMap7_2.get(key); - } - - get fun intMap7_3(): map { - return self.intMap7_3; - } - - get fun intMap7_3Value(key: Int): Int? { - return self.intMap7_3.get(key); - } - - get fun intMap7_4(): map { - return self.intMap7_4; - } - - get fun intMap7_4Value(key: Int): Int? { - return self.intMap7_4.get(key); - } - - get fun intMap7_5(): map { - return self.intMap7_5; - } - - get fun intMap7_5Value(key: Int): Int? { - return self.intMap7_5.get(key); - } - - get fun intMap7_6(): map { - return self.intMap7_6; - } - - get fun intMap7_6Value(key: Int): Int? { - return self.intMap7_6.get(key); - } - - get fun intMap8_1(): map { - return self.intMap8_1; - } - - get fun intMap8_1Value(key: Int): Int? { - return self.intMap8_1.get(key); - } - - get fun intMap8_2(): map { - return self.intMap8_2; - } - - get fun intMap8_2Value(key: Int): Int? { - return self.intMap8_2.get(key); - } - - get fun intMap8_3(): map { - return self.intMap8_3; - } - - get fun intMap8_3Value(key: Int): Int? { - return self.intMap8_3.get(key); - } - - get fun intMap8_4(): map { - return self.intMap8_4; - } - - get fun intMap8_4Value(key: Int): Int? { - return self.intMap8_4.get(key); - } - - get fun intMap8_5(): map { - return self.intMap8_5; - } - - get fun intMap8_5Value(key: Int): Int? { - return self.intMap8_5.get(key); - } - - get fun intMap8_6(): map { - return self.intMap8_6; - } - - get fun intMap8_6Value(key: Int): Int? { - return self.intMap8_6.get(key); - } - - get fun intMap8_7(): map { - return self.intMap8_7; - } - - get fun intMap8_7Value(key: Int): Int? { - return self.intMap8_7.get(key); - } - - get fun intMap9_1(): map { - return self.intMap9_1; - } - - get fun intMap9_1Value(key: Int): Int? { - return self.intMap9_1.get(key); - } - - get fun intMap9_2(): map { - return self.intMap9_2; - } - - get fun intMap9_2Value(key: Int): Int? { - return self.intMap9_2.get(key); - } - - get fun intMap9_3(): map { - return self.intMap9_3; - } - - get fun intMap9_3Value(key: Int): Int? { - return self.intMap9_3.get(key); - } - - get fun intMap9_4(): map { - return self.intMap9_4; - } - - get fun intMap9_4Value(key: Int): Int? { - return self.intMap9_4.get(key); - } - - get fun intMap9_5(): map { - return self.intMap9_5; - } - - get fun intMap9_5Value(key: Int): Int? { - return self.intMap9_5.get(key); - } - - get fun intMap9_6(): map { - return self.intMap9_6; - } - - get fun intMap9_6Value(key: Int): Int? { - return self.intMap9_6.get(key); - } - - get fun intMap10_1(): map { - return self.intMap10_1; - } - - get fun intMap10_1Value(key: Int): Int? { - return self.intMap10_1.get(key); - } - - get fun intMap10_2(): map { - return self.intMap10_2; - } - - get fun intMap10_2Value(key: Int): Int? { - return self.intMap10_2.get(key); - } - - get fun intMap10_3(): map { - return self.intMap10_3; - } - - get fun intMap10_3Value(key: Int): Int? { - return self.intMap10_3.get(key); - } - - get fun intMap10_4(): map { - return self.intMap10_4; - } - - get fun intMap10_4Value(key: Int): Int? { - return self.intMap10_4.get(key); - } - - // - // Int as Key inside the code (not storage) - // - - get fun intMap10Value(key: Int, value: Int): Int { - let map1: map = emptyMap(); - let map2: map = emptyMap(); - let map3: map = emptyMap(); - let map4: map = emptyMap(); - let map5: map = emptyMap(); - let map6: map = emptyMap(); - let map7: map = emptyMap(); - - map1.set(key, value); - map2.set(key, value); - map3.set(key, value); - map4.set(key, value); - map5.set(key, value); - map6.set(key, value); - map7.set(key, value); - - let value1: Int = map1.get(key)!!; - let value2: Int = map2.get(key)!!; - let value3: Int = map3.get(key)!!; - let value4: Int = map4.get(key)!!; - let value5: Int = map5.get(key)!!; - let value6: Int = map6.get(key)!!; - let value7: Int = map7.get(key)!!; - - return value1 + value2 + value3 + value4 + value5 + value6 + value7; - } - - get fun intMap11Value(key: Int, value: Int): Int { - let map1: map = emptyMap(); - let map2: map = emptyMap(); - let map3: map = emptyMap(); - let map4: map = emptyMap(); - let map5: map = emptyMap(); - let map6: map = emptyMap(); - - map1.set(key, value); - map2.set(key, value); - map3.set(key, value); - map4.set(key, value); - map5.set(key, value); - map6.set(key, value); - - let value1: Int = map1.get(key)!!; - let value2: Int = map2.get(key)!!; - let value3: Int = map3.get(key)!!; - let value4: Int = map4.get(key)!!; - let value5: Int = map5.get(key)!!; - let value6: Int = map6.get(key)!!; - - return value1 + value2 + value3 + value4 + value5 + value6; - } - - get fun intMap12Value(key: Int, value: Int): Int { - let map1: map = emptyMap(); - let map2: map = emptyMap(); - let map3: map = emptyMap(); - let map4: map = emptyMap(); - let map5: map = emptyMap(); - let map6: map = emptyMap(); - let map7: map = emptyMap(); - - map1.set(key, value); - map2.set(key, value); - map3.set(key, value); - map4.set(key, value); - map5.set(key, value); - map6.set(key, value); - map7.set(key, value); - - let value1: Int = map1.get(key)!!; - let value2: Int = map2.get(key)!!; - let value3: Int = map3.get(key)!!; - let value4: Int = map4.get(key)!!; - let value5: Int = map5.get(key)!!; - let value6: Int = map6.get(key)!!; - let value7: Int = map7.get(key)!!; - - return value1 + value2 + value3 + value4 + value5 + value6 + value7; - } - - get fun intMap13Value(key: Int, value: Int): Int { - let map1: map = emptyMap(); - let map2: map = emptyMap(); - let map3: map = emptyMap(); - let map4: map = emptyMap(); - let map5: map = emptyMap(); - let map6: map = emptyMap(); - let map7: map = emptyMap(); - - map1.set(key, value); - map2.set(key, value); - map3.set(key, value); - map4.set(key, value); - map5.set(key, value); - map6.set(key, value); - map7.set(key, value); - - let value1: Int = map1.get(key)!!; - let value2: Int = map2.get(key)!!; - let value3: Int = map3.get(key)!!; - let value4: Int = map4.get(key)!!; - let value5: Int = map5.get(key)!!; - let value6: Int = map6.get(key)!!; - let value7: Int = map7.get(key)!!; - - return value1 + value2 + value3 + value4 + value5 + value6 + value7; - } - - get fun intMap14Value(key: Int, value: Int): Int { - let map1: map = emptyMap(); - let map2: map = emptyMap(); - let map3: map = emptyMap(); - let map4: map = emptyMap(); - - map1.set(key, value); - map2.set(key, value); - map3.set(key, value); - map4.set(key, value); - - let value1: Int = map1.get(key)!!; - let value2: Int = map2.get(key)!!; - let value3: Int = map3.get(key)!!; - let value4: Int = map4.get(key)!!; - - return value1 + value2 + value3 + value4; - } - - // - // Address Keys - // - - addrMap1: map; - addrMap2: map; - addrMap3: map; - addrMap4: map; - addrMap5: map; - - addrMap6_1: map; - addrMap6_2: map; - addrMap6_3: map; - addrMap6_4: map; - addrMap6_5: map; - addrMap6_6: map; - addrMap6_7: map; - - addrMap7_1: map; - addrMap7_2: map; - addrMap7_3: map; - addrMap7_4: map; - addrMap7_5: map; - addrMap7_6: map; - - receive(msg: SetAddrMap1) { - self.addrMap1.set(msg.key, msg.value); - } - - receive(msg: SetAddrMap2) { - self.addrMap2.set(msg.key, msg.value); - } - - receive(msg: SetAddrMap3) { - self.addrMap3.set(msg.key, msg.value); - } - - receive(msg: SetAddrMap4) { - self.addrMap4.set(msg.key, msg.value); - } - - receive(msg: SetAddrMap5) { - self.addrMap5.set(msg.key, msg.value); - } - - receive(msg: SetAddrMap6) { - self.addrMap6_1.set(msg.key, msg.value); - self.addrMap6_2.set(msg.key, msg.value); - self.addrMap6_3.set(msg.key, msg.value); - self.addrMap6_4.set(msg.key, msg.value); - self.addrMap6_5.set(msg.key, msg.value); - self.addrMap6_6.set(msg.key, msg.value); - self.addrMap6_7.set(msg.key, msg.value); - } - - receive(msg: SetAddrMap7) { - self.addrMap7_1.set(msg.key, msg.value); - self.addrMap7_2.set(msg.key, msg.value); - self.addrMap7_3.set(msg.key, msg.value); - self.addrMap7_4.set(msg.key, msg.value); - self.addrMap7_5.set(msg.key, msg.value); - self.addrMap7_6.set(msg.key, msg.value); - } - - receive(msg: DelAddrMap1) { - self.addrMap1.del(msg.key); - } - - receive(msg: DelAddrMap2) { - self.addrMap2.del(msg.key); - } - - receive(msg: DelAddrMap3) { - self.addrMap3.del(msg.key); - } - - receive(msg: DelAddrMap4) { - self.addrMap4.del(msg.key); - } - - receive(msg: DelAddrMap5) { - self.addrMap5.del(msg.key); - } - - receive(msg: DelAddrMap6) { - self.addrMap6_1.del(msg.key); - self.addrMap6_2.del(msg.key); - self.addrMap6_3.del(msg.key); - self.addrMap6_4.del(msg.key); - self.addrMap6_5.del(msg.key); - self.addrMap6_6.del(msg.key); - self.addrMap6_7.del(msg.key); - } - - receive(msg: DelAddrMap7) { - self.addrMap7_1.del(msg.key); - self.addrMap7_2.del(msg.key); - self.addrMap7_3.del(msg.key); - self.addrMap7_4.del(msg.key); - self.addrMap7_5.del(msg.key); - self.addrMap7_6.del(msg.key); - } - - receive("reset") { - self.addrMap1 = emptyMap(); - self.addrMap2 = emptyMap(); - self.addrMap3 = emptyMap(); - self.addrMap4 = emptyMap(); - self.addrMap5 = emptyMap(); - - self.intMap1 = emptyMap(); - self.intMap2 = emptyMap(); - self.intMap3 = emptyMap(); - self.intMap4 = emptyMap(); - self.intMap5 = emptyMap(); - } - - get fun addrMap1(): map { - return self.addrMap1; - } - - get fun addrMap1Value(key: Address): Int? { - return self.addrMap1.get(key); - } - - get fun addrMap2(): map { - return self.addrMap2; - } - - get fun addrMap2Value(key: Address): Bool? { - return self.addrMap2.get(key); - } - - get fun addrMap3(): map { - return self.addrMap3; - } - - get fun addrMap3Value(key: Address): Cell? { - return self.addrMap3.get(key); - } - - get fun addrMap4(): map { - return self.addrMap4; - } - - get fun addrMap4Value(key: Address): SomeStruct? { - return self.addrMap4.get(key); - } - - get fun addrMap5(): map { - return self.addrMap5; - } - - get fun addrMap5Value(key: Address): Address? { - return self.addrMap5.get(key); - } - - get fun addrMap6_1(): map { - return self.addrMap6_1; - } - - get fun addrMap6_1Value(key: Address): Int? { - return self.addrMap6_1.get(key); - } - - get fun addrMap6_2(): map { - return self.addrMap6_2; - } - - get fun addrMap6_2Value(key: Address): Int? { - return self.addrMap6_2.get(key); - } - - get fun addrMap6_3(): map { - return self.addrMap6_3; - } - - get fun addrMap6_3Value(key: Address): Int? { - return self.addrMap6_3.get(key); - } - - get fun addrMap6_4(): map { - return self.addrMap6_4; - } - - get fun addrMap6_4Value(key: Address): Int? { - return self.addrMap6_4.get(key); - } - - get fun addrMap6_5(): map { - return self.addrMap6_5; - } - - get fun addrMap6_5Value(key: Address): Int? { - return self.addrMap6_5.get(key); - } - - get fun addrMap6_6(): map { - return self.addrMap6_6; - } - - get fun addrMap6_6Value(key: Address): Int? { - return self.addrMap6_6.get(key); - } - - get fun addrMap6_7(): map { - return self.addrMap6_7; - } - - get fun addrMap6_7Value(key: Address): Int? { - return self.addrMap6_7.get(key); - } - - get fun addrMap7_1(): map { - return self.addrMap7_1; - } - - get fun addrMap7_1Value(key: Address): Int? { - return self.addrMap7_1.get(key); - } - - get fun addrMap7_2(): map { - return self.addrMap7_2; - } - - get fun addrMap7_2Value(key: Address): Int? { - return self.addrMap7_2.get(key); - } - - get fun addrMap7_3(): map { - return self.addrMap7_3; - } - - get fun addrMap7_3Value(key: Address): Int? { - return self.addrMap7_3.get(key); - } - - get fun addrMap7_4(): map { - return self.addrMap7_4; - } - - get fun addrMap7_4Value(key: Address): Int? { - return self.addrMap7_4.get(key); - } - - get fun addrMap7_5(): map { - return self.addrMap7_5; - } - - get fun addrMap7_5Value(key: Address): Int? { - return self.addrMap7_5.get(key); - } - - get fun addrMap7_6(): map { - return self.addrMap7_6; - } - - get fun addrMap7_6Value(key: Address): Int? { - return self.addrMap7_6.get(key); - } - - get fun mapAsCell(): Cell? { - return self.addrMap7_6.asCell(); - } - - get fun intMap1IsEmpty(): Bool { - return self.intMap1.isEmpty(); - } - - get fun intMap1Del(key: Int): Bool { - return self.intMap1.del(key); - } - get fun checkNullReference(): Int { let m: map = emptyMap(); return m.get(0)!!; @@ -1036,44 +1936,4 @@ contract MapTestContract { let m: map = emptyMap(); m.get(0)!!; } - - get fun intMap1Exists(key: Int): Bool { - return self.intMap1.exists(key); - } - - get fun intMap2Exists(key: Int): Bool { - return self.intMap2.exists(key); - } - - get fun intMap3Exists(key: Int): Bool { - return self.intMap3.exists(key); - } - - get fun intMap4Exists(key: Int): Bool { - return self.intMap4.exists(key); - } - - get fun intMap5Exists(key: Int): Bool { - return self.intMap5.exists(key); - } - - get fun addrMap1Exists(key: Address): Bool { - return self.addrMap1.exists(key); - } - - get fun addrMap2Exists(key: Address): Bool { - return self.addrMap2.exists(key); - } - - get fun addrMap3Exists(key: Address): Bool { - return self.addrMap3.exists(key); - } - - get fun addrMap4Exists(key: Address): Bool { - return self.addrMap4.exists(key); - } - - get fun addrMap5Exists(key: Address): Bool { - return self.addrMap5.exists(key); - } } diff --git a/src/test/e2e-emulated/map.spec.ts b/src/test/e2e-emulated/map.spec.ts index d52a6a80b..def08f733 100644 --- a/src/test/e2e-emulated/map.spec.ts +++ b/src/test/e2e-emulated/map.spec.ts @@ -1,1310 +1,2132 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ + import { randomAddress } from "../utils/randomAddress"; import { MapTestContract, + MapTestContract$Data, + SetAllMaps, + DelAllMaps, SomeStruct, + ReplaceAllMaps, + ReplaceGetAllMaps, } from "./contracts/output/maps_MapTestContract"; import { Blockchain, SandboxContract, TreasuryContract } from "@ton/sandbox"; -import { beginCell, toNano } from "@ton/core"; -import { ComputeError } from "@ton/core"; +import { Address, beginCell, Cell, Dictionary, toNano } from "@ton/core"; import "@ton/test-utils"; -function strEq(a: SomeStruct | null, b: SomeStruct | null) { - if (a === null || b === null) { - return a === b; - } - return a.value === b.value; +// Type Guard for SomeStruct +function isSomeStruct(value: unknown): value is SomeStruct { + return ( + typeof value === "object" && + value !== null && + "$$type" in value && + (value as { $$type: string }).$$type === "SomeStruct" && + "int" in value && + "bool" in value && + "address" in value && + "a" in value && + "b" in value && + typeof (value as any).int === "bigint" && + typeof (value as any).bool === "boolean" && + (value as any).address instanceof Address && + typeof (value as any).a === "bigint" && + typeof (value as any).b === "bigint" + ); +} + +// Comparator for SomeStruct +function compareStructs(a: SomeStruct, b: SomeStruct): boolean { + return ( + a.int === b.int && + a.bool === b.bool && + a.address.equals(b.address) && + a.a === b.a && + a.b === b.b + ); } -describe("map", () => { +// Type definitions for keys and values to make them type-safe +type TestKeys = { + keyInt: bigint; + keyInt8: bigint; + keyInt42: bigint; + keyInt256: bigint; + keyUint8: bigint; + keyUint42: bigint; + keyUint256: bigint; + keyAddress: Address; +}; + +type TestValues = { + valueInt: bigint; + valueInt8: bigint; + valueInt42: bigint; + valueInt256: bigint; + valueUint8: bigint; + valueUint42: bigint; + valueUint256: bigint; + valueBool: boolean; + valueCell: Cell; + valueAddress: Address; + valueStruct: SomeStruct; +}; + +// Configuration for all maps +type MapConfig = { + mapName: keyof MapTestContract$Data; + key: keyof TestKeys; + value: keyof TestValues; + keyTransform?: (key: any) => any; + valueTransform?: (value: any) => any; +}; + +type TestCase = { + keys: TestKeys; + values: TestValues; +}; + +const testCases: TestCase[] = [ + { + keys: { + keyInt: 123n, + keyInt8: -10n, + keyInt42: 42n, + keyInt256: 456n, + keyUint8: 200n, + keyUint42: 500_000n, + keyUint256: 1_000_000_000_000n, + keyAddress: randomAddress(0, "address0"), + }, + values: { + valueInt: 999n, + valueInt8: -128n, + valueInt42: 123_456n, + valueInt256: 789n, + valueUint8: 255n, + valueUint42: 123_456_789n, + valueUint256: 999_999_999_999n, + valueBool: true, + valueCell: beginCell().storeUint(42, 32).endCell(), + valueAddress: randomAddress(0, "address"), + valueStruct: { + $$type: "SomeStruct", + int: 321n, + bool: false, + address: randomAddress(0, "address"), + a: 10n, + b: -20n, + } as SomeStruct, + }, + }, + { + keys: { + keyInt: -(2n ** 31n), // Min 32-bit signed int + keyInt8: -128n, // Min 8-bit signed int + keyInt42: -(2n ** 41n), // Min 42-bit signed int + keyInt256: -(2n ** 255n), // Min 256-bit signed int + keyUint8: 255n, // Max 8-bit unsigned int + keyUint42: 2n ** 42n - 1n, // Max 42-bit unsigned int + keyUint256: 2n ** 256n - 1n, // Max 256-bit unsigned int + keyAddress: randomAddress(0, "address1"), + }, + values: { + valueInt: 2n ** 31n - 1n, // Max 32-bit signed int + valueInt8: 127n, // Max 8-bit signed int + valueInt42: 2n ** 41n - 1n, // Max 42-bit signed int + valueInt256: 2n ** 255n - 1n, // Max 256-bit signed int + valueUint8: 0n, // Min unsigned int + valueUint42: 0n, // Min unsigned int + valueUint256: 0n, // Min unsigned int + valueBool: false, + valueCell: beginCell() + .storeUint(2n ** 32n - 1n, 32) + .endCell(), + valueAddress: randomAddress(0, "address"), + valueStruct: { + $$type: "SomeStruct", + int: -(2n ** 31n), // Min 32-bit signed int + bool: true, + address: randomAddress(0, "address"), + a: 2n ** 41n - 1n, // Max 42-bit signed int + b: -(2n ** 41n), // Min 42-bit signed int + } as SomeStruct, + }, + }, + { + keys: { + keyInt: 0n, + keyInt8: 0n, + keyInt42: 0n, + keyInt256: 0n, + keyUint8: 0n, + keyUint42: 0n, + keyUint256: 0n, + keyAddress: randomAddress(0, "address2"), + }, + values: { + valueInt: 1n, + valueInt8: -1n, + valueInt42: -1n, + valueInt256: 1n, + valueUint8: 1n, + valueUint42: 1n, + valueUint256: 1n, + valueBool: false, + valueCell: beginCell().storeUint(0, 32).endCell(), + valueAddress: randomAddress(0, "address"), + valueStruct: { + $$type: "SomeStruct", + int: 0n, + bool: false, + address: randomAddress(0, "address"), + a: 0n, + b: 0n, + } as SomeStruct, + }, + }, + { + keys: { + keyInt: 1n, + keyInt8: -1n, + keyInt42: 424n, + keyInt256: 2n ** 128n, // Large but not maximum value + keyUint8: 128n, // Middle value + keyUint42: 2n ** 41n, // Large power of 2 + keyUint256: 2n ** 128n, // Large power of 2 + keyAddress: randomAddress(0, "address3"), + }, + values: { + valueInt: -1n, + valueInt8: -127n, // Near min but not quite + valueInt42: 2n ** 40n, // Large power of 2 + valueInt256: -(2n ** 254n), // Large negative power of 2 + valueUint8: 128n, // Middle value + valueUint42: 2n ** 41n, // Large power of 2 + valueUint256: 2n ** 255n, // Large power of 2 + valueBool: true, + valueCell: beginCell() + .storeUint(2n ** 31n, 32) + .endCell(), + valueAddress: randomAddress(0, "address"), + valueStruct: { + $$type: "SomeStruct", + int: -42n, // Special number + bool: true, + address: randomAddress(0, "address"), + a: 2n ** 40n, // Large power of 2 + b: -(2n ** 40n), // Large negative power of 2 + } as SomeStruct, + }, + }, +]; + +// Define all 88 map configurations +const mapConfigs: MapConfig[] = [ + // int_* Maps + { mapName: "int_int", key: "keyInt", value: "valueInt" }, + { + mapName: "int_int8", + key: "keyInt", + value: "valueInt8", + valueTransform: (v: bigint) => Number(v), + }, + { mapName: "int_int42", key: "keyInt", value: "valueInt42" }, + { mapName: "int_int256", key: "keyInt", value: "valueInt256" }, + { + mapName: "int_uint8", + key: "keyInt", + value: "valueUint8", + valueTransform: (v: bigint) => Number(v), + }, + { mapName: "int_uint42", key: "keyInt", value: "valueUint42" }, + { mapName: "int_uint256", key: "keyInt", value: "valueUint256" }, + { mapName: "int_bool", key: "keyInt", value: "valueBool" }, + { mapName: "int_cell", key: "keyInt", value: "valueCell" }, + { mapName: "int_address", key: "keyInt", value: "valueAddress" }, + { mapName: "int_struct", key: "keyInt", value: "valueStruct" }, + + // int8_* Maps + { + mapName: "int8_int", + key: "keyInt8", + value: "valueInt", + keyTransform: (k: bigint) => Number(k), + }, + { + mapName: "int8_int8", + key: "keyInt8", + value: "valueInt8", + keyTransform: (k: bigint) => Number(k), + valueTransform: (v: bigint) => Number(v), + }, + { + mapName: "int8_int42", + key: "keyInt8", + value: "valueInt42", + keyTransform: (k: bigint) => Number(k), + }, + { + mapName: "int8_int256", + key: "keyInt8", + value: "valueInt256", + keyTransform: (k: bigint) => Number(k), + }, + { + mapName: "int8_uint8", + key: "keyInt8", + value: "valueUint8", + keyTransform: (k: bigint) => Number(k), + valueTransform: (v: bigint) => Number(v), + }, + { + mapName: "int8_uint42", + key: "keyInt8", + value: "valueUint42", + keyTransform: (k: bigint) => Number(k), + }, + { + mapName: "int8_uint256", + key: "keyInt8", + value: "valueUint256", + keyTransform: (k: bigint) => Number(k), + }, + { + mapName: "int8_bool", + key: "keyInt8", + value: "valueBool", + keyTransform: (k: bigint) => Number(k), + }, + { + mapName: "int8_cell", + key: "keyInt8", + value: "valueCell", + keyTransform: (k: bigint) => Number(k), + }, + { + mapName: "int8_address", + key: "keyInt8", + value: "valueAddress", + keyTransform: (k: bigint) => Number(k), + }, + { + mapName: "int8_struct", + key: "keyInt8", + value: "valueStruct", + keyTransform: (k: bigint) => Number(k), + }, + + // int42_* Maps + { mapName: "int42_int", key: "keyInt42", value: "valueInt" }, + { + mapName: "int42_int8", + key: "keyInt42", + value: "valueInt8", + valueTransform: (v: bigint) => Number(v), + }, + { mapName: "int42_int42", key: "keyInt42", value: "valueInt42" }, + { mapName: "int42_int256", key: "keyInt42", value: "valueInt256" }, + { + mapName: "int42_uint8", + key: "keyInt42", + value: "valueUint8", + valueTransform: (v: bigint) => Number(v), + }, + { mapName: "int42_uint42", key: "keyInt42", value: "valueUint42" }, + { mapName: "int42_uint256", key: "keyInt42", value: "valueUint256" }, + { mapName: "int42_bool", key: "keyInt42", value: "valueBool" }, + { mapName: "int42_cell", key: "keyInt42", value: "valueCell" }, + { mapName: "int42_address", key: "keyInt42", value: "valueAddress" }, + { mapName: "int42_struct", key: "keyInt42", value: "valueStruct" }, + + // int256_* Maps + { mapName: "int256_int", key: "keyInt256", value: "valueInt" }, + { + mapName: "int256_int8", + key: "keyInt256", + value: "valueInt8", + valueTransform: (v: bigint) => Number(v), + }, + { mapName: "int256_int42", key: "keyInt256", value: "valueInt42" }, + { mapName: "int256_int256", key: "keyInt256", value: "valueInt256" }, + { + mapName: "int256_uint8", + key: "keyInt256", + value: "valueUint8", + valueTransform: (v: bigint) => Number(v), + }, + { mapName: "int256_uint42", key: "keyInt256", value: "valueUint42" }, + { mapName: "int256_uint256", key: "keyInt256", value: "valueUint256" }, + { mapName: "int256_bool", key: "keyInt256", value: "valueBool" }, + { mapName: "int256_cell", key: "keyInt256", value: "valueCell" }, + { mapName: "int256_address", key: "keyInt256", value: "valueAddress" }, + { mapName: "int256_struct", key: "keyInt256", value: "valueStruct" }, + + // uint8_* Maps + { + mapName: "uint8_int", + key: "keyUint8", + value: "valueInt", + keyTransform: (k: bigint) => Number(k), + }, + { + mapName: "uint8_int8", + key: "keyUint8", + value: "valueInt8", + keyTransform: (k: bigint) => Number(k), + valueTransform: (v: bigint) => Number(v), + }, + { + mapName: "uint8_int42", + key: "keyUint8", + value: "valueInt42", + keyTransform: (k: bigint) => Number(k), + }, + { + mapName: "uint8_int256", + key: "keyUint8", + value: "valueInt256", + keyTransform: (k: bigint) => Number(k), + }, + { + mapName: "uint8_uint8", + key: "keyUint8", + value: "valueUint8", + keyTransform: (k: bigint) => Number(k), + valueTransform: (v: bigint) => Number(v), + }, + { + mapName: "uint8_uint42", + key: "keyUint8", + value: "valueUint42", + keyTransform: (k: bigint) => Number(k), + }, + { + mapName: "uint8_uint256", + key: "keyUint8", + value: "valueUint256", + keyTransform: (k: bigint) => Number(k), + }, + { + mapName: "uint8_bool", + key: "keyUint8", + value: "valueBool", + keyTransform: (k: bigint) => Number(k), + }, + { + mapName: "uint8_cell", + key: "keyUint8", + value: "valueCell", + keyTransform: (k: bigint) => Number(k), + }, + { + mapName: "uint8_address", + key: "keyUint8", + value: "valueAddress", + keyTransform: (k: bigint) => Number(k), + }, + { + mapName: "uint8_struct", + key: "keyUint8", + value: "valueStruct", + keyTransform: (k: bigint) => Number(k), + }, + + // uint42_* Maps + { mapName: "uint42_int", key: "keyUint42", value: "valueInt" }, + { + mapName: "uint42_int8", + key: "keyUint42", + value: "valueInt8", + valueTransform: (v: bigint) => Number(v), + }, + { mapName: "uint42_int42", key: "keyUint42", value: "valueInt42" }, + { mapName: "uint42_int256", key: "keyUint42", value: "valueInt256" }, + { + mapName: "uint42_uint8", + key: "keyUint42", + value: "valueUint8", + valueTransform: (v: bigint) => Number(v), + }, + { mapName: "uint42_uint42", key: "keyUint42", value: "valueUint42" }, + { mapName: "uint42_uint256", key: "keyUint42", value: "valueUint256" }, + { mapName: "uint42_bool", key: "keyUint42", value: "valueBool" }, + { mapName: "uint42_cell", key: "keyUint42", value: "valueCell" }, + { mapName: "uint42_address", key: "keyUint42", value: "valueAddress" }, + { mapName: "uint42_struct", key: "keyUint42", value: "valueStruct" }, + + // uint256_* Maps + { mapName: "uint256_int", key: "keyUint256", value: "valueInt" }, + { + mapName: "uint256_int8", + key: "keyUint256", + value: "valueInt8", + valueTransform: (v: bigint) => Number(v), + }, + { mapName: "uint256_int42", key: "keyUint256", value: "valueInt42" }, + { mapName: "uint256_int256", key: "keyUint256", value: "valueInt256" }, + { + mapName: "uint256_uint8", + key: "keyUint256", + value: "valueUint8", + valueTransform: (v: bigint) => Number(v), + }, + { mapName: "uint256_uint42", key: "keyUint256", value: "valueUint42" }, + { mapName: "uint256_uint256", key: "keyUint256", value: "valueUint256" }, + { mapName: "uint256_bool", key: "keyUint256", value: "valueBool" }, + { mapName: "uint256_cell", key: "keyUint256", value: "valueCell" }, + { mapName: "uint256_address", key: "keyUint256", value: "valueAddress" }, + { mapName: "uint256_struct", key: "keyUint256", value: "valueStruct" }, + + // address_* Maps + { mapName: "address_int", key: "keyAddress", value: "valueInt" }, + { + mapName: "address_int8", + key: "keyAddress", + value: "valueInt8", + valueTransform: (v: bigint) => Number(v), + }, + { mapName: "address_int42", key: "keyAddress", value: "valueInt42" }, + { mapName: "address_int256", key: "keyAddress", value: "valueInt256" }, + { + mapName: "address_uint8", + key: "keyAddress", + value: "valueUint8", + valueTransform: (v: bigint) => Number(v), + }, + { mapName: "address_uint42", key: "keyAddress", value: "valueUint42" }, + { mapName: "address_uint256", key: "keyAddress", value: "valueUint256" }, + { mapName: "address_bool", key: "keyAddress", value: "valueBool" }, + { mapName: "address_cell", key: "keyAddress", value: "valueCell" }, + { mapName: "address_address", key: "keyAddress", value: "valueAddress" }, + { mapName: "address_struct", key: "keyAddress", value: "valueStruct" }, +]; + +describe("MapTestContract", () => { let blockchain: Blockchain; - let treasure: SandboxContract; + let treasury: SandboxContract; let contract: SandboxContract; beforeEach(async () => { + // Initialize the blockchain and contracts blockchain = await Blockchain.create(); blockchain.verbosity.print = false; - treasure = await blockchain.treasury("treasure"); + treasury = await blockchain.treasury("treasury"); contract = blockchain.openContract(await MapTestContract.fromInit()); + + // Fund the contract with some TONs await contract.send( - treasure.getSender(), + treasury.getSender(), { value: toNano("10") }, null, ); + + // Check that all maps are empty initially + const maps = await contract.getAllMaps(); + for (const [_mapName, map] of Object.entries(maps)) { + if (map instanceof Dictionary) { + expect(map.size).toBe(0); + } + } + }); + + it("set: should set and clear values", async () => { + for (const { keys, values } of testCases) { + // Send the set operation + const setMessage: SetAllMaps = { + $$type: "SetAllMaps", + ...keys, + ...values, + }; + + await contract.send( + treasury.getSender(), + { value: toNano("1") }, + setMessage, + ); + + // Retrieve all maps using `allMaps` getter + const allMaps = await contract.getAllMaps(); + + // Iterate over mapConfigs and perform assertions + mapConfigs.forEach( + ({ mapName, key, value, keyTransform, valueTransform }) => { + const map = allMaps[mapName] as Dictionary; + + expect(map.size).toBe(1); + + let mapKey = keys[key]; + if (keyTransform) { + mapKey = keyTransform(mapKey); + } + + let expectedValue = values[value]; + if (valueTransform) { + expectedValue = valueTransform(expectedValue); + } + + const actualValue = map.get(mapKey); + + if (expectedValue instanceof Cell) { + expect(actualValue).toEqualCell(expectedValue); + } else if (expectedValue instanceof Address) { + expect(actualValue).toEqualAddress(expectedValue); + } else if (isSomeStruct(expectedValue)) { + expect(compareStructs(actualValue, expectedValue)).toBe( + true, + ); + } else { + expect(actualValue).toEqual(expectedValue); + } + }, + ); + + // Clear all maps by setting values to null + const clearMessage: SetAllMaps = { + $$type: "SetAllMaps", + ...keys, + valueInt: null, + valueInt8: null, + valueInt42: null, + valueInt256: null, + valueUint8: null, + valueUint42: null, + valueUint256: null, + valueBool: null, + valueCell: null, + valueAddress: null, + valueStruct: null, + }; + + await contract.send( + treasury.getSender(), + { value: toNano("1") }, + clearMessage, + ); + + // Retrieve all maps again to ensure they are empty + const clearedMaps = await contract.getAllMaps(); + + // Iterate over mapConfigs and assert maps are empty + mapConfigs.forEach(({ mapName }) => { + const map = clearedMaps[mapName] as Dictionary; + expect(map.size).toBe(0); + }); + } + }); + + it("set: should set multiple values", async () => { + for (const { keys, values } of testCases) { + // Send the set operation + const setMessage: SetAllMaps = { + $$type: "SetAllMaps", + ...keys, + ...values, + }; + + await contract.send( + treasury.getSender(), + { value: toNano("1") }, + setMessage, + ); + } + + // Retrieve all maps using `allMaps` getter + const allMaps = await contract.getAllMaps(); + + for (const { keys, values } of testCases) { + // Iterate over mapConfigs and perform assertions + mapConfigs.forEach( + ({ mapName, key, value, keyTransform, valueTransform }) => { + const map = allMaps[mapName] as Dictionary; + + expect(map.size).toBe(testCases.length); + + let mapKey = keys[key]; + if (keyTransform) { + mapKey = keyTransform(mapKey); + } + + let expectedValue = values[value]; + if (valueTransform) { + expectedValue = valueTransform(expectedValue); + } + + const actualValue = map.get(mapKey); + + if (expectedValue instanceof Cell) { + expect(actualValue).toEqualCell(expectedValue); + } else if (expectedValue instanceof Address) { + expect(actualValue).toEqualAddress(expectedValue); + } else if (isSomeStruct(expectedValue)) { + expect(compareStructs(actualValue, expectedValue)).toBe( + true, + ); + } else { + expect(actualValue).toEqual(expectedValue); + } + }, + ); + } + + for (const { keys } of testCases) { + // Clear all maps by setting values to null + const clearMessage: SetAllMaps = { + $$type: "SetAllMaps", + ...keys, + valueInt: null, + valueInt8: null, + valueInt42: null, + valueInt256: null, + valueUint8: null, + valueUint42: null, + valueUint256: null, + valueBool: null, + valueCell: null, + valueAddress: null, + valueStruct: null, + }; + + await contract.send( + treasury.getSender(), + { value: toNano("1") }, + clearMessage, + ); + } + + // Retrieve all maps again to ensure they are empty + const clearedMaps = await contract.getAllMaps(); + + // Iterate over mapConfigs and assert maps are empty + mapConfigs.forEach(({ mapName }) => { + const map = clearedMaps[mapName] as Dictionary; + expect(map.size).toBe(0); + }); }); - it("should implement maps correctly", async () => { - jest.setTimeout(2 * 60000); - try { - // Initial state - expect((await contract.getIntMap1()).size).toBe(0); - expect(await contract.getIntMap1IsEmpty()).toBe(true); - expect((await contract.getIntMap2()).size).toBe(0); - expect((await contract.getIntMap3()).size).toBe(0); - expect((await contract.getIntMap4()).size).toBe(0); - expect((await contract.getIntMap5()).size).toBe(0); - expect((await contract.getIntMap6_1()).size).toBe(0); - expect((await contract.getIntMap6_2()).size).toBe(0); - expect((await contract.getIntMap6_3()).size).toBe(0); - expect((await contract.getIntMap6_4()).size).toBe(0); - expect((await contract.getIntMap6_5()).size).toBe(0); - expect((await contract.getIntMap6_6()).size).toBe(0); - expect((await contract.getIntMap6_7()).size).toBe(0); - expect((await contract.getIntMap7_1()).size).toBe(0); - expect((await contract.getIntMap7_2()).size).toBe(0); - expect((await contract.getIntMap7_3()).size).toBe(0); - expect((await contract.getIntMap7_4()).size).toBe(0); - expect((await contract.getIntMap7_5()).size).toBe(0); - expect((await contract.getIntMap7_6()).size).toBe(0); - expect((await contract.getIntMap8_1()).size).toBe(0); - expect((await contract.getIntMap8_2()).size).toBe(0); - expect((await contract.getIntMap8_3()).size).toBe(0); - expect((await contract.getIntMap8_4()).size).toBe(0); - expect((await contract.getIntMap8_5()).size).toBe(0); - expect((await contract.getIntMap8_6()).size).toBe(0); - expect((await contract.getIntMap8_7()).size).toBe(0); - expect((await contract.getIntMap9_1()).size).toBe(0); - expect((await contract.getIntMap9_2()).size).toBe(0); - expect((await contract.getIntMap9_3()).size).toBe(0); - expect((await contract.getIntMap9_4()).size).toBe(0); - expect((await contract.getIntMap9_5()).size).toBe(0); - expect((await contract.getIntMap9_6()).size).toBe(0); - expect((await contract.getIntMap10_1()).size).toBe(0); - expect((await contract.getIntMap10_2()).size).toBe(0); - expect((await contract.getIntMap10_3()).size).toBe(0); - expect((await contract.getIntMap10_4()).size).toBe(0); - expect((await contract.getAddrMap1()).size).toBe(0); - expect((await contract.getAddrMap2()).size).toBe(0); - expect((await contract.getAddrMap3()).size).toBe(0); - expect((await contract.getAddrMap4()).size).toBe(0); - expect((await contract.getAddrMap6_1()).size).toBe(0); - expect((await contract.getAddrMap6_2()).size).toBe(0); - expect((await contract.getAddrMap6_3()).size).toBe(0); - expect((await contract.getAddrMap6_4()).size).toBe(0); - expect((await contract.getAddrMap6_5()).size).toBe(0); - expect((await contract.getAddrMap6_6()).size).toBe(0); - expect((await contract.getAddrMap6_7()).size).toBe(0); - expect((await contract.getAddrMap7_1()).size).toBe(0); - expect((await contract.getAddrMap7_2()).size).toBe(0); - expect((await contract.getAddrMap7_3()).size).toBe(0); - expect((await contract.getAddrMap7_4()).size).toBe(0); - expect((await contract.getAddrMap7_5()).size).toBe(0); - expect((await contract.getAddrMap7_6()).size).toBe(0); - - // Keys for test - const keys: bigint[] = []; - keys.push(1n); - keys.push(0n); - keys.push(-1n); - keys.push(10102312312312312312312n); - keys.push(-10102312312312312312312n); - for (const k of keys) { - // Check keys to be empty - expect(await contract.getIntMap1Value(k)).toBeNull(); - expect(await contract.getIntMap2Value(k)).toBeNull(); - expect(await contract.getIntMap3Value(k)).toBeNull(); - expect(await contract.getIntMap4Value(k)).toBeNull(); - - // Set keys - const valueInt = k * 10n; - const valueBool = k < 0n; - const addr = randomAddress(0, "addr-" + k.toString(10)); - const valueCell = beginCell().storeUint(123123, 128).endCell(); - const valueStruct: SomeStruct = { - $$type: "SomeStruct", - value: 10012312n, + it("set: should overwrite values", async () => { + for (const { keys } of testCases) { + for (const { values } of testCases) { + // Send the set operation + const setMessage: SetAllMaps = { + $$type: "SetAllMaps", + ...keys, + ...values, }; - const valueAddr = randomAddress(0, "value-" + k.toString(10)); - const keySmall = k % 100n; - const keySmallAbs = (k > 0 ? k : -k) % 100n; - const valueSmall = k % 100n; - const valueSmallAbs = (k > 0 ? k : -k) % 100n; - // Send set transactions - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetIntMap1", key: k, value: valueInt }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetIntMap2", key: k, value: valueBool }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetIntMap3", key: k, value: valueCell }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetIntMap4", key: k, value: valueStruct }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetIntMap5", key: k, value: valueAddr }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetIntMap6", key: keySmall, value: valueInt }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { - $$type: "SetUIntMap7", - key: keySmallAbs, - value: valueInt, - }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetIntMap8", key: k, value: valueSmall }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetUIntMap9", key: k, value: valueSmallAbs }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { - $$type: "SetUIntMap10", - key: keySmallAbs, - value: valueSmallAbs, - }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetAddrMap1", key: addr, value: valueInt }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetAddrMap2", key: addr, value: valueBool }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetAddrMap3", key: addr, value: valueCell }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetAddrMap4", key: addr, value: valueStruct }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetAddrMap5", key: addr, value: valueAddr }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetAddrMap6", key: addr, value: valueSmall }, - ); await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetAddrMap7", key: addr, value: valueSmallAbs }, + treasury.getSender(), + { value: toNano("1") }, + setMessage, ); - expect(await contract.getIntMap1Value(k)).toBe(valueInt); - expect((await contract.getIntMap2Value(k))!).toBe(valueBool); - expect( - (await contract.getIntMap3Value(k))!.equals(valueCell), - ).toBe(true); - expect( - strEq((await contract.getIntMap4Value(k))!, valueStruct), - ).toBe(true); - expect( - (await contract.getIntMap5Value(k))!.equals(valueAddr), - ).toBe(true); - expect(await contract.getIntMap6_1Value(keySmall)).toBe( - valueInt, - ); - expect(await contract.getIntMap6_2Value(keySmall)).toBe( - valueInt, - ); - expect(await contract.getIntMap6_3Value(keySmall)).toBe( - valueInt, - ); - expect(await contract.getIntMap6_4Value(keySmall)).toBe( - valueInt, - ); - expect(await contract.getIntMap6_5Value(keySmall)).toBe( - valueInt, - ); - expect(await contract.getIntMap6_6Value(keySmall)).toBe( - valueInt, - ); - expect(await contract.getIntMap6_7Value(keySmall)).toBe( - valueInt, - ); - expect(await contract.getIntMap7_1Value(keySmallAbs)).toBe( - valueInt, - ); - expect(await contract.getIntMap7_2Value(keySmallAbs)).toBe( - valueInt, - ); - expect(await contract.getIntMap7_3Value(keySmallAbs)).toBe( - valueInt, - ); - expect(await contract.getIntMap7_4Value(keySmallAbs)).toBe( - valueInt, - ); - expect(await contract.getIntMap7_5Value(keySmallAbs)).toBe( - valueInt, - ); - expect(await contract.getIntMap7_6Value(keySmallAbs)).toBe( - valueInt, - ); - expect(await contract.getIntMap8_1Value(k)).toBe(valueSmall); - expect(await contract.getIntMap8_2Value(k)).toBe(valueSmall); - expect(await contract.getIntMap8_3Value(k)).toBe(valueSmall); - expect(await contract.getIntMap8_4Value(k)).toBe(valueSmall); - expect(await contract.getIntMap8_5Value(k)).toBe(valueSmall); - expect(await contract.getIntMap8_6Value(k)).toBe(valueSmall); - expect(await contract.getIntMap8_7Value(k)).toBe(valueSmall); - expect(await contract.getIntMap9_1Value(k)).toBe(valueSmallAbs); - expect(await contract.getIntMap9_2Value(k)).toBe(valueSmallAbs); - expect(await contract.getIntMap9_3Value(k)).toBe(valueSmallAbs); - expect(await contract.getIntMap9_4Value(k)).toBe(valueSmallAbs); - expect(await contract.getIntMap9_5Value(k)).toBe(valueSmallAbs); - expect(await contract.getIntMap9_6Value(k)).toBe(valueSmallAbs); - expect(await contract.getIntMap10_1Value(keySmallAbs)).toBe( - valueSmallAbs, - ); - expect(await contract.getIntMap10_2Value(keySmallAbs)).toBe( - valueSmallAbs, - ); - expect(await contract.getIntMap10_3Value(keySmallAbs)).toBe( - valueSmallAbs, - ); - expect(await contract.getIntMap10_4Value(keySmallAbs)).toBe( - valueSmallAbs, - ); - expect( - await contract.getIntMap10Value(keySmall, valueInt), - ).toBe(valueInt * 7n); - expect( - await contract.getIntMap11Value(keySmallAbs, valueInt), - ).toBe(valueInt * 6n); - expect(await contract.getIntMap12Value(k, valueSmall)).toBe( - valueSmall * 7n, - ); - expect(await contract.getIntMap13Value(k, valueSmallAbs)).toBe( - valueSmallAbs * 7n, - ); - expect( - await contract.getIntMap14Value(keySmallAbs, valueSmallAbs), - ).toBe(valueSmallAbs * 4n); - expect(await contract.getAddrMap1Value(addr)).toBe(valueInt); - expect((await contract.getAddrMap2Value(addr))!).toBe( - valueBool, - ); - expect( - (await contract.getAddrMap3Value(addr))!.equals(valueCell), - ).toBe(true); - expect( - strEq( - (await contract.getAddrMap4Value(addr))!, - valueStruct, - ), - ).toBe(true); - expect( - (await contract.getAddrMap5Value(addr))!.equals(valueAddr), - ).toBe(true); - expect(await contract.getAddrMap6_1Value(addr)).toBe( - valueSmall, - ); - expect(await contract.getAddrMap6_2Value(addr)).toBe( - valueSmall, - ); - expect(await contract.getAddrMap6_3Value(addr)).toBe( - valueSmall, - ); - expect(await contract.getAddrMap6_4Value(addr)).toBe( - valueSmall, - ); - expect(await contract.getAddrMap6_5Value(addr)).toBe( - valueSmall, - ); - expect(await contract.getAddrMap6_6Value(addr)).toBe( - valueSmall, - ); - expect(await contract.getAddrMap6_7Value(addr)).toBe( - valueSmall, - ); - expect(await contract.getAddrMap7_1Value(addr)).toBe( - valueSmallAbs, - ); - expect(await contract.getAddrMap7_2Value(addr)).toBe( - valueSmallAbs, - ); - expect(await contract.getAddrMap7_3Value(addr)).toBe( - valueSmallAbs, - ); - expect(await contract.getAddrMap7_4Value(addr)).toBe( - valueSmallAbs, - ); - expect(await contract.getAddrMap7_5Value(addr)).toBe( - valueSmallAbs, - ); - expect(await contract.getAddrMap7_6Value(addr)).toBe( - valueSmallAbs, - ); + // Retrieve all maps using `allMaps` getter + const allMaps = await contract.getAllMaps(); - // Sizes - expect((await contract.getIntMap1()).size).toBe(1); - expect((await contract.getIntMap2()).size).toBe(1); - expect((await contract.getIntMap3()).size).toBe(1); - expect((await contract.getIntMap4()).size).toBe(1); - expect((await contract.getIntMap5()).size).toBe(1); - expect((await contract.getIntMap6_1()).size).toBe(1); - expect((await contract.getIntMap6_2()).size).toBe(1); - expect((await contract.getIntMap6_3()).size).toBe(1); - expect((await contract.getIntMap6_4()).size).toBe(1); - expect((await contract.getIntMap6_5()).size).toBe(1); - expect((await contract.getIntMap6_6()).size).toBe(1); - expect((await contract.getIntMap6_7()).size).toBe(1); - expect((await contract.getIntMap7_1()).size).toBe(1); - expect((await contract.getIntMap7_2()).size).toBe(1); - expect((await contract.getIntMap7_3()).size).toBe(1); - expect((await contract.getIntMap7_4()).size).toBe(1); - expect((await contract.getIntMap7_5()).size).toBe(1); - expect((await contract.getIntMap7_6()).size).toBe(1); - expect((await contract.getIntMap8_1()).size).toBe(1); - expect((await contract.getIntMap8_2()).size).toBe(1); - expect((await contract.getIntMap8_3()).size).toBe(1); - expect((await contract.getIntMap8_4()).size).toBe(1); - expect((await contract.getIntMap8_5()).size).toBe(1); - expect((await contract.getIntMap8_6()).size).toBe(1); - expect((await contract.getIntMap8_7()).size).toBe(1); - expect((await contract.getIntMap9_1()).size).toBe(1); - expect((await contract.getIntMap9_2()).size).toBe(1); - expect((await contract.getIntMap9_3()).size).toBe(1); - expect((await contract.getIntMap9_4()).size).toBe(1); - expect((await contract.getIntMap9_5()).size).toBe(1); - expect((await contract.getIntMap9_6()).size).toBe(1); - expect((await contract.getIntMap10_1()).size).toBe(1); - expect((await contract.getIntMap10_2()).size).toBe(1); - expect((await contract.getIntMap10_3()).size).toBe(1); - expect((await contract.getIntMap10_4()).size).toBe(1); - expect((await contract.getAddrMap1()).size).toBe(1); - expect((await contract.getAddrMap2()).size).toBe(1); - expect((await contract.getAddrMap3()).size).toBe(1); - expect((await contract.getAddrMap4()).size).toBe(1); - - // Clear keys - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetIntMap1", key: k, value: null }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetIntMap2", key: k, value: null }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetIntMap3", key: k, value: null }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetIntMap4", key: k, value: null }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetIntMap5", key: k, value: null }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetIntMap6", key: keySmall, value: null }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetUIntMap7", key: keySmallAbs, value: null }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetIntMap8", key: k, value: null }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetUIntMap9", key: k, value: null }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetUIntMap10", key: keySmallAbs, value: null }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetAddrMap1", key: addr, value: null }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetAddrMap2", key: addr, value: null }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetAddrMap3", key: addr, value: null }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetAddrMap4", key: addr, value: null }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetAddrMap5", key: addr, value: null }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetAddrMap6", key: addr, value: null }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetAddrMap7", key: addr, value: null }, - ); + // Iterate over mapConfigs and perform assertions + mapConfigs.forEach( + ({ mapName, key, value, keyTransform, valueTransform }) => { + const map = allMaps[mapName] as Dictionary; - // Check value cleared - expect(await contract.getIntMap1Value(k)).toBeNull(); - expect(await contract.getIntMap2Value(k)).toBeNull(); - expect(await contract.getIntMap3Value(k)).toBeNull(); - expect(await contract.getIntMap4Value(k)).toBeNull(); - expect(await contract.getIntMap5Value(k)).toBeNull(); - expect(await contract.getIntMap6_1Value(keySmall)).toBe(null); - expect(await contract.getIntMap6_2Value(keySmall)).toBe(null); - expect(await contract.getIntMap6_3Value(keySmall)).toBe(null); - expect(await contract.getIntMap6_4Value(keySmall)).toBe(null); - expect(await contract.getIntMap6_5Value(keySmall)).toBe(null); - expect(await contract.getIntMap6_6Value(keySmall)).toBe(null); - expect(await contract.getIntMap6_7Value(keySmall)).toBe(null); - expect(await contract.getIntMap7_1Value(keySmallAbs)).toBe( - null, - ); - expect(await contract.getIntMap7_2Value(keySmallAbs)).toBe( - null, - ); - expect(await contract.getIntMap7_3Value(keySmallAbs)).toBe( - null, - ); - expect(await contract.getIntMap7_4Value(keySmallAbs)).toBe( - null, - ); - expect(await contract.getIntMap7_5Value(keySmallAbs)).toBe( - null, - ); - expect(await contract.getIntMap7_6Value(keySmallAbs)).toBe( - null, - ); - expect(await contract.getIntMap8_1Value(k)).toBe(null); - expect(await contract.getIntMap8_2Value(k)).toBe(null); - expect(await contract.getIntMap8_3Value(k)).toBe(null); - expect(await contract.getIntMap8_4Value(k)).toBe(null); - expect(await contract.getIntMap8_5Value(k)).toBe(null); - expect(await contract.getIntMap8_6Value(k)).toBe(null); - expect(await contract.getIntMap8_7Value(k)).toBe(null); - expect(await contract.getIntMap9_1Value(k)).toBe(null); - expect(await contract.getIntMap9_2Value(k)).toBe(null); - expect(await contract.getIntMap9_3Value(k)).toBe(null); - expect(await contract.getIntMap9_4Value(k)).toBe(null); - expect(await contract.getIntMap9_5Value(k)).toBe(null); - expect(await contract.getIntMap9_6Value(k)).toBe(null); - expect(await contract.getIntMap10_1Value(keySmallAbs)).toBe( - null, - ); - expect(await contract.getIntMap10_2Value(keySmallAbs)).toBe( - null, - ); - expect(await contract.getIntMap10_3Value(keySmallAbs)).toBe( - null, - ); - expect(await contract.getIntMap10_4Value(keySmallAbs)).toBe( - null, + expect(map.size).toBe(1); + + let mapKey = keys[key]; + if (keyTransform) { + mapKey = keyTransform(mapKey); + } + + let expectedValue = values[value]; + if (valueTransform) { + expectedValue = valueTransform(expectedValue); + } + + const actualValue = map.get(mapKey); + + if (expectedValue instanceof Cell) { + expect(actualValue).toEqualCell(expectedValue); + } else if (expectedValue instanceof Address) { + expect(actualValue).toEqualAddress(expectedValue); + } else if (isSomeStruct(expectedValue)) { + expect( + compareStructs(actualValue, expectedValue), + ).toBe(true); + } else { + expect(actualValue).toEqual(expectedValue); + } + }, ); - expect(await contract.getAddrMap1Value(addr)).toBeNull(); - expect(await contract.getAddrMap2Value(addr)).toBeNull(); - expect(await contract.getAddrMap3Value(addr)).toBeNull(); - expect(await contract.getAddrMap4Value(addr)).toBeNull(); - expect(await contract.getAddrMap5Value(addr)).toBeNull(); - expect(await contract.getAddrMap6_1Value(addr)).toBe(null); - expect(await contract.getAddrMap6_2Value(addr)).toBe(null); - expect(await contract.getAddrMap6_3Value(addr)).toBe(null); - expect(await contract.getAddrMap6_4Value(addr)).toBe(null); - expect(await contract.getAddrMap6_5Value(addr)).toBe(null); - expect(await contract.getAddrMap6_6Value(addr)).toBe(null); - expect(await contract.getAddrMap6_7Value(addr)).toBe(null); - expect(await contract.getAddrMap7_1Value(addr)).toBe(null); - expect(await contract.getAddrMap7_2Value(addr)).toBe(null); - expect(await contract.getAddrMap7_3Value(addr)).toBe(null); - expect(await contract.getAddrMap7_4Value(addr)).toBe(null); - expect(await contract.getAddrMap7_5Value(addr)).toBe(null); - expect(await contract.getAddrMap7_6Value(addr)).toBe(null); } - // Test isEmpty + // Clear all maps by setting values to null + const clearMessage: SetAllMaps = { + $$type: "SetAllMaps", + ...keys, + valueInt: null, + valueInt8: null, + valueInt42: null, + valueInt256: null, + valueUint8: null, + valueUint42: null, + valueUint256: null, + valueBool: null, + valueCell: null, + valueAddress: null, + valueStruct: null, + }; + + await contract.send( + treasury.getSender(), + { value: toNano("1") }, + clearMessage, + ); + + // Retrieve all maps again to ensure they are empty + const clearedMaps = await contract.getAllMaps(); - expect(await contract.getIntMap1IsEmpty()).toBe(true); + // Iterate over mapConfigs and assert maps are empty + mapConfigs.forEach(({ mapName }) => { + const map = clearedMaps[mapName] as Dictionary; + expect(map.size).toBe(0); + }); + } + }); + + it("get: should get values after setting them and nulls after clearing", async () => { + for (const { keys, values } of testCases) { + // Send the set operation + const setMessage: SetAllMaps = { + $$type: "SetAllMaps", + ...keys, + ...values, + }; await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetIntMap1", key: 1n, value: 1n }, + treasury.getSender(), + { value: toNano("1") }, + setMessage, + ); + + // Call the .get operation on all maps + const getResponse = await contract.getGetAllMaps( + keys.keyInt, + keys.keyInt8, + keys.keyInt42, + keys.keyInt256, + keys.keyUint8, + keys.keyUint42, + keys.keyUint256, + keys.keyAddress, + ); + + // Iterate over mapConfigs and perform assertions + mapConfigs.forEach( + ({ + mapName, + key: _key, + value, + keyTransform: _keyTransform, + valueTransform, + }) => { + let expectedValue = values[value]; + let actualValue = getResponse[mapName]; + + if (valueTransform) { + expectedValue = valueTransform(expectedValue); + actualValue = valueTransform(actualValue); + } + + if (expectedValue instanceof Cell) { + expect(actualValue).toEqualCell(expectedValue); + } else if (expectedValue instanceof Address) { + expect(actualValue).toEqualAddress(expectedValue); + } else if (isSomeStruct(expectedValue)) { + expect( + compareStructs( + actualValue as SomeStruct, + expectedValue, + ), + ).toBe(true); + } else { + expect(actualValue).toEqual(expectedValue); + } + }, ); - expect(await contract.getIntMap1IsEmpty()).toBe(false); + // Clear all maps by setting values to null + const clearMessage: SetAllMaps = { + $$type: "SetAllMaps", + ...keys, + valueInt: null, + valueInt8: null, + valueInt42: null, + valueInt256: null, + valueUint8: null, + valueUint42: null, + valueUint256: null, + valueBool: null, + valueCell: null, + valueAddress: null, + valueStruct: null, + }; await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetIntMap1", key: 1n, value: null }, + treasury.getSender(), + { value: toNano("1") }, + clearMessage, + ); + + // Call the .get operation on all maps again + const clearedGetResponse = await contract.getGetAllMaps( + keys.keyInt, + keys.keyInt8, + keys.keyInt42, + keys.keyInt256, + keys.keyUint8, + keys.keyUint42, + keys.keyUint256, + keys.keyAddress, + ); + + // Iterate over mapConfigs and assert maps are empty + mapConfigs.forEach(({ mapName }) => { + const actualValue = clearedGetResponse[mapName]; + expect(actualValue).toBeNull(); + }); + } + }); + + it("get: should return null for all maps when no values are set", async () => { + for (const { keys } of testCases) { + // Call the .get operation on all maps + const getResponse = await contract.getGetAllMaps( + keys.keyInt, + keys.keyInt8, + keys.keyInt42, + keys.keyInt256, + keys.keyUint8, + keys.keyUint42, + keys.keyUint256, + keys.keyAddress, ); - expect(await contract.getIntMap1IsEmpty()).toBe(true); + // Iterate over mapConfigs and assert that all values are null + mapConfigs.forEach(({ mapName }) => { + const actualValue = getResponse[mapName]; + expect(actualValue).toBeNull(); + }); + } + }); + + it("get: should retrieve multiple values after setting them", async () => { + // Set multiple values + for (const { keys, values } of testCases) { + const setMessage: SetAllMaps = { + $$type: "SetAllMaps", + ...keys, + ...values, + }; + + await contract.send( + treasury.getSender(), + { value: toNano("1") }, + setMessage, + ); + } - await expect(contract.getCheckNullReference()).rejects.toThrow( - "Unable to execute get method. Got exit_code: 128", + // Now retrieve values for each test case + for (const { keys, values } of testCases) { + // Call the .get operation on all maps + const getResponse = await contract.getGetAllMaps( + keys.keyInt, + keys.keyInt8, + keys.keyInt42, + keys.keyInt256, + keys.keyUint8, + keys.keyUint42, + keys.keyUint256, + keys.keyAddress, ); - const result = await contract.send( - treasure.getSender(), - { - value: toNano(1), + // Iterate over mapConfigs and perform assertions + mapConfigs.forEach( + ({ + mapName, + key: _key, + value, + keyTransform: _keyTransform, + valueTransform, + }) => { + let expectedValue = values[value]; + let actualValue = getResponse[mapName]; + + if (valueTransform) { + expectedValue = valueTransform(expectedValue); + actualValue = valueTransform(actualValue); + } + + if (expectedValue instanceof Cell) { + expect(actualValue).toEqualCell(expectedValue); + } else if (expectedValue instanceof Address) { + expect(actualValue).toEqualAddress(expectedValue); + } else if (isSomeStruct(expectedValue)) { + expect( + compareStructs( + actualValue as SomeStruct, + expectedValue, + ), + ).toBe(true); + } else { + expect(actualValue).toEqual(expectedValue); + } }, - { $$type: "CheckNullReference" }, ); - expect(result.transactions).toHaveTransaction({ - from: treasure.address, - to: contract.address, - success: false, - exitCode: 128, - }); - } catch (e) { - if (e instanceof ComputeError) { - if (e.logs) { - console.warn(e.logs); - } - } - throw e; } }); - it("should implement key deletion correctly", async () => { - jest.setTimeout(2 * 60000); - try { - // Initial state - expect((await contract.getIntMap1()).size).toBe(0); - expect((await contract.getIntMap2()).size).toBe(0); - expect((await contract.getIntMap3()).size).toBe(0); - expect((await contract.getIntMap4()).size).toBe(0); - expect((await contract.getIntMap5()).size).toBe(0); - expect((await contract.getIntMap6_1()).size).toBe(0); - expect((await contract.getIntMap6_2()).size).toBe(0); - expect((await contract.getIntMap6_3()).size).toBe(0); - expect((await contract.getIntMap6_4()).size).toBe(0); - expect((await contract.getIntMap6_5()).size).toBe(0); - expect((await contract.getIntMap6_6()).size).toBe(0); - expect((await contract.getIntMap6_7()).size).toBe(0); - expect((await contract.getIntMap7_1()).size).toBe(0); - expect((await contract.getIntMap7_2()).size).toBe(0); - expect((await contract.getIntMap7_3()).size).toBe(0); - expect((await contract.getIntMap7_4()).size).toBe(0); - expect((await contract.getIntMap7_5()).size).toBe(0); - expect((await contract.getIntMap7_6()).size).toBe(0); - expect((await contract.getIntMap8_1()).size).toBe(0); - expect((await contract.getIntMap8_2()).size).toBe(0); - expect((await contract.getIntMap8_3()).size).toBe(0); - expect((await contract.getIntMap8_4()).size).toBe(0); - expect((await contract.getIntMap8_5()).size).toBe(0); - expect((await contract.getIntMap8_6()).size).toBe(0); - expect((await contract.getIntMap8_7()).size).toBe(0); - expect((await contract.getIntMap9_1()).size).toBe(0); - expect((await contract.getIntMap9_2()).size).toBe(0); - expect((await contract.getIntMap9_3()).size).toBe(0); - expect((await contract.getIntMap9_4()).size).toBe(0); - expect((await contract.getIntMap9_5()).size).toBe(0); - expect((await contract.getIntMap9_6()).size).toBe(0); - expect((await contract.getIntMap10_1()).size).toBe(0); - expect((await contract.getIntMap10_2()).size).toBe(0); - expect((await contract.getIntMap10_3()).size).toBe(0); - expect((await contract.getIntMap10_4()).size).toBe(0); - expect((await contract.getAddrMap1()).size).toBe(0); - expect((await contract.getAddrMap2()).size).toBe(0); - expect((await contract.getAddrMap3()).size).toBe(0); - expect((await contract.getAddrMap4()).size).toBe(0); - expect((await contract.getAddrMap6_1()).size).toBe(0); - expect((await contract.getAddrMap6_2()).size).toBe(0); - expect((await contract.getAddrMap6_3()).size).toBe(0); - expect((await contract.getAddrMap6_4()).size).toBe(0); - expect((await contract.getAddrMap6_5()).size).toBe(0); - expect((await contract.getAddrMap6_6()).size).toBe(0); - expect((await contract.getAddrMap6_7()).size).toBe(0); - expect((await contract.getAddrMap7_1()).size).toBe(0); - expect((await contract.getAddrMap7_2()).size).toBe(0); - expect((await contract.getAddrMap7_3()).size).toBe(0); - expect((await contract.getAddrMap7_4()).size).toBe(0); - expect((await contract.getAddrMap7_5()).size).toBe(0); - expect((await contract.getAddrMap7_6()).size).toBe(0); - - // Keys for test - const keys: bigint[] = []; - keys.push(1n); - keys.push(0n); - keys.push(-1n); - keys.push(10102312312312312312312n); - keys.push(-10102312312312312312312n); - for (const k of keys) { - // Check keys to be empty - expect(await contract.getIntMap1Value(k)).toBeNull(); - expect(await contract.getIntMap2Value(k)).toBeNull(); - expect(await contract.getIntMap3Value(k)).toBeNull(); - expect(await contract.getIntMap4Value(k)).toBeNull(); - - // Set keys - const valueInt = k * 10n; - const valueBool = k < 0n; - const addr = randomAddress(0, "addr-" + k.toString(10)); - const valueCell = beginCell().storeUint(123123, 128).endCell(); - const valueStruct: SomeStruct = { - $$type: "SomeStruct", - value: 10012312n, + it("get: should retrieve updated values after overwriting", async () => { + for (const { keys } of testCases) { + for (const { values } of testCases) { + // Send the set operation + const setMessage: SetAllMaps = { + $$type: "SetAllMaps", + ...keys, + ...values, }; - const valueAddr = randomAddress(0, "value-" + k.toString(10)); - const keySmall = k % 100n; - const keySmallAbs = (k > 0 ? k : -k) % 100n; - const valueSmall = k % 100n; - const valueSmallAbs = (k > 0 ? k : -k) % 100n; - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetIntMap1", key: k, value: valueInt }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetIntMap2", key: k, value: valueBool }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetIntMap3", key: k, value: valueCell }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetIntMap4", key: k, value: valueStruct }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetIntMap5", key: k, value: valueAddr }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetIntMap6", key: keySmall, value: valueInt }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { - $$type: "SetUIntMap7", - key: keySmallAbs, - value: valueInt, - }, - ); + await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetIntMap8", key: k, value: valueSmall }, + treasury.getSender(), + { value: toNano("1") }, + setMessage, ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetUIntMap9", key: k, value: valueSmallAbs }, + + // Call the .get operation on all maps + const getResponse = await contract.getGetAllMaps( + keys.keyInt, + keys.keyInt8, + keys.keyInt42, + keys.keyInt256, + keys.keyUint8, + keys.keyUint42, + keys.keyUint256, + keys.keyAddress, ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { - $$type: "SetUIntMap10", - key: keySmallAbs, - value: valueSmallAbs, + + // Iterate over mapConfigs and perform assertions + mapConfigs.forEach( + ({ + mapName, + key: _key, + value, + keyTransform: _keyTransform, + valueTransform, + }) => { + let expectedValue = values[value]; + let actualValue = getResponse[mapName]; + + if (valueTransform) { + expectedValue = valueTransform(expectedValue); + actualValue = valueTransform(actualValue); + } + + if (expectedValue instanceof Cell) { + expect(actualValue).toEqualCell(expectedValue); + } else if (expectedValue instanceof Address) { + expect(actualValue).toEqualAddress(expectedValue); + } else if (isSomeStruct(expectedValue)) { + expect( + compareStructs( + actualValue as SomeStruct, + expectedValue, + ), + ).toBe(true); + } else { + expect(actualValue).toEqual(expectedValue); + } }, ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetAddrMap1", key: addr, value: valueInt }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetAddrMap2", key: addr, value: valueBool }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetAddrMap3", key: addr, value: valueCell }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetAddrMap4", key: addr, value: valueStruct }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetAddrMap5", key: addr, value: valueAddr }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetAddrMap6", key: addr, value: valueSmall }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetAddrMap7", key: addr, value: valueSmallAbs }, - ); + } + } + }); - // Check value set - expect(await contract.getIntMap1Value(k)).toBe(valueInt); - expect((await contract.getIntMap2Value(k))!).toBe(valueBool); - expect( - (await contract.getIntMap3Value(k))!.equals(valueCell), - ).toBe(true); - expect( - strEq((await contract.getIntMap4Value(k))!, valueStruct), - ).toBe(true); - expect( - (await contract.getIntMap5Value(k))!.equals(valueAddr), - ).toBe(true); - expect(await contract.getIntMap6_1Value(keySmall)).toBe( - valueInt, - ); - expect(await contract.getIntMap6_2Value(keySmall)).toBe( - valueInt, - ); - expect(await contract.getIntMap6_3Value(keySmall)).toBe( - valueInt, - ); - expect(await contract.getIntMap6_4Value(keySmall)).toBe( - valueInt, - ); - expect(await contract.getIntMap6_5Value(keySmall)).toBe( - valueInt, - ); - expect(await contract.getIntMap6_6Value(keySmall)).toBe( - valueInt, - ); - expect(await contract.getIntMap6_7Value(keySmall)).toBe( - valueInt, - ); - expect(await contract.getIntMap7_1Value(keySmallAbs)).toBe( - valueInt, - ); - expect(await contract.getIntMap7_2Value(keySmallAbs)).toBe( - valueInt, - ); - expect(await contract.getIntMap7_3Value(keySmallAbs)).toBe( - valueInt, - ); - expect(await contract.getIntMap7_4Value(keySmallAbs)).toBe( - valueInt, - ); - expect(await contract.getIntMap7_5Value(keySmallAbs)).toBe( - valueInt, - ); - expect(await contract.getIntMap7_6Value(keySmallAbs)).toBe( - valueInt, - ); - expect(await contract.getIntMap8_1Value(k)).toBe(valueSmall); - expect(await contract.getIntMap8_2Value(k)).toBe(valueSmall); - expect(await contract.getIntMap8_3Value(k)).toBe(valueSmall); - expect(await contract.getIntMap8_4Value(k)).toBe(valueSmall); - expect(await contract.getIntMap8_5Value(k)).toBe(valueSmall); - expect(await contract.getIntMap8_6Value(k)).toBe(valueSmall); - expect(await contract.getIntMap8_7Value(k)).toBe(valueSmall); - expect(await contract.getIntMap9_1Value(k)).toBe(valueSmallAbs); - expect(await contract.getIntMap9_2Value(k)).toBe(valueSmallAbs); - expect(await contract.getIntMap9_3Value(k)).toBe(valueSmallAbs); - expect(await contract.getIntMap9_4Value(k)).toBe(valueSmallAbs); - expect(await contract.getIntMap9_5Value(k)).toBe(valueSmallAbs); - expect(await contract.getIntMap9_6Value(k)).toBe(valueSmallAbs); - expect(await contract.getIntMap10_1Value(keySmallAbs)).toBe( - valueSmallAbs, - ); - expect(await contract.getIntMap10_2Value(keySmallAbs)).toBe( - valueSmallAbs, - ); - expect(await contract.getIntMap10_3Value(keySmallAbs)).toBe( - valueSmallAbs, - ); - expect(await contract.getIntMap10_4Value(keySmallAbs)).toBe( - valueSmallAbs, - ); - expect( - await contract.getIntMap10Value(keySmall, valueInt), - ).toBe(valueInt * 7n); - expect( - await contract.getIntMap11Value(keySmallAbs, valueInt), - ).toBe(valueInt * 6n); - expect(await contract.getIntMap12Value(k, valueSmall)).toBe( - valueSmall * 7n, - ); - expect(await contract.getIntMap13Value(k, valueSmallAbs)).toBe( - valueSmallAbs * 7n, - ); - expect( - await contract.getIntMap14Value(keySmallAbs, valueSmallAbs), - ).toBe(valueSmallAbs * 4n); - expect( - await contract.getIntMap14Value(keySmallAbs, valueSmallAbs), - ).toBe(valueSmallAbs * 4n); - expect(await contract.getAddrMap1Value(addr)).toBe(valueInt); - expect((await contract.getAddrMap2Value(addr))!).toBe( - valueBool, - ); - expect( - (await contract.getAddrMap3Value(addr))!.equals(valueCell), - ).toBe(true); - expect( - strEq( - (await contract.getAddrMap4Value(addr))!, - valueStruct, - ), - ).toBe(true); - expect( - (await contract.getAddrMap5Value(addr))!.equals(valueAddr), - ).toBe(true); - expect(await contract.getAddrMap6_1Value(addr)).toBe( - valueSmall, - ); - expect(await contract.getAddrMap6_2Value(addr)).toBe( - valueSmall, - ); - expect(await contract.getAddrMap6_3Value(addr)).toBe( - valueSmall, - ); - expect(await contract.getAddrMap6_4Value(addr)).toBe( - valueSmall, - ); - expect(await contract.getAddrMap6_5Value(addr)).toBe( - valueSmall, - ); - expect(await contract.getAddrMap6_6Value(addr)).toBe( - valueSmall, - ); - expect(await contract.getAddrMap6_7Value(addr)).toBe( - valueSmall, - ); - expect(await contract.getAddrMap7_1Value(addr)).toBe( - valueSmallAbs, - ); - expect(await contract.getAddrMap7_2Value(addr)).toBe( - valueSmallAbs, - ); - expect(await contract.getAddrMap7_3Value(addr)).toBe( - valueSmallAbs, - ); - expect(await contract.getAddrMap7_4Value(addr)).toBe( - valueSmallAbs, - ); - expect(await contract.getAddrMap7_5Value(addr)).toBe( - valueSmallAbs, - ); - expect(await contract.getAddrMap7_6Value(addr)).toBe( - valueSmallAbs, - ); + it("get: should return null for non-existent keys", async () => { + // First, set some keys + for (const { keys, values } of testCases.slice(0, -1)) { + const setMessage: SetAllMaps = { + $$type: "SetAllMaps", + ...keys, + ...values, + }; - // Sizes - expect((await contract.getIntMap1()).size).toBe(1); - expect((await contract.getIntMap2()).size).toBe(1); - expect((await contract.getIntMap3()).size).toBe(1); - expect((await contract.getIntMap4()).size).toBe(1); - expect((await contract.getIntMap5()).size).toBe(1); - expect((await contract.getIntMap6_1()).size).toBe(1); - expect((await contract.getIntMap6_2()).size).toBe(1); - expect((await contract.getIntMap6_3()).size).toBe(1); - expect((await contract.getIntMap6_4()).size).toBe(1); - expect((await contract.getIntMap6_5()).size).toBe(1); - expect((await contract.getIntMap6_6()).size).toBe(1); - expect((await contract.getIntMap6_7()).size).toBe(1); - expect((await contract.getIntMap7_1()).size).toBe(1); - expect((await contract.getIntMap7_2()).size).toBe(1); - expect((await contract.getIntMap7_3()).size).toBe(1); - expect((await contract.getIntMap7_4()).size).toBe(1); - expect((await contract.getIntMap7_5()).size).toBe(1); - expect((await contract.getIntMap7_6()).size).toBe(1); - expect((await contract.getIntMap8_1()).size).toBe(1); - expect((await contract.getIntMap8_2()).size).toBe(1); - expect((await contract.getIntMap8_3()).size).toBe(1); - expect((await contract.getIntMap8_4()).size).toBe(1); - expect((await contract.getIntMap8_5()).size).toBe(1); - expect((await contract.getIntMap8_6()).size).toBe(1); - expect((await contract.getIntMap8_7()).size).toBe(1); - expect((await contract.getIntMap9_1()).size).toBe(1); - expect((await contract.getIntMap9_2()).size).toBe(1); - expect((await contract.getIntMap9_3()).size).toBe(1); - expect((await contract.getIntMap9_4()).size).toBe(1); - expect((await contract.getIntMap9_5()).size).toBe(1); - expect((await contract.getIntMap9_6()).size).toBe(1); - expect((await contract.getIntMap10_1()).size).toBe(1); - expect((await contract.getIntMap10_2()).size).toBe(1); - expect((await contract.getIntMap10_3()).size).toBe(1); - expect((await contract.getIntMap10_4()).size).toBe(1); - expect((await contract.getAddrMap1()).size).toBe(1); - expect((await contract.getAddrMap2()).size).toBe(1); - expect((await contract.getAddrMap3()).size).toBe(1); - expect((await contract.getAddrMap4()).size).toBe(1); - - // Check .del return value - expect(await contract.getIntMap1Del(k)).toBe(true); - expect(await contract.getIntMap1Del(k + 1n)).toBe(false); - - // Clear keys - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "DelIntMap1", key: k }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "DelIntMap2", key: k }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "DelIntMap3", key: k }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "DelIntMap4", key: k }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "DelIntMap5", key: k }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "DelIntMap6", key: keySmall }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "DelUIntMap7", key: keySmallAbs }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "DelIntMap8", key: k }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "DelUIntMap9", key: k }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "DelUIntMap10", key: keySmallAbs }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "DelAddrMap1", key: addr }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "DelAddrMap2", key: addr }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "DelAddrMap3", key: addr }, - ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "DelAddrMap4", key: addr }, - ); + await contract.send( + treasury.getSender(), + { value: toNano("1") }, + setMessage, + ); + } + + // Now, attempt to get values for keys that have not been set + const nonExistentKeys = testCases[testCases.length - 1]!.keys; + + const getResponse = await contract.getGetAllMaps( + nonExistentKeys.keyInt, + nonExistentKeys.keyInt8, + nonExistentKeys.keyInt42, + nonExistentKeys.keyInt256, + nonExistentKeys.keyUint8, + nonExistentKeys.keyUint42, + nonExistentKeys.keyUint256, + nonExistentKeys.keyAddress, + ); + + // Iterate over mapConfigs and assert that values are null + mapConfigs.forEach(({ mapName }) => { + const actualValue = getResponse[mapName]; + expect(actualValue).toBeNull(); + }); + }); + + it("del: should delete values", async () => { + for (const { keys, values } of testCases) { + // Send the set operation + const setMessage: SetAllMaps = { + $$type: "SetAllMaps", + ...keys, + ...values, + }; + + await contract.send( + treasury.getSender(), + { value: toNano("1") }, + setMessage, + ); + + // Retrieve all maps using `allMaps` getter to ensure they are set + const allMapsBeforeDel = await contract.getAllMaps(); + + // Iterate over mapConfigs and verify all maps have one entry + mapConfigs.forEach( + ({ mapName, key, value, keyTransform, valueTransform }) => { + const map = allMapsBeforeDel[mapName] as Dictionary< + any, + any + >; + + expect(map.size).toBe(1); + + let mapKey = keys[key]; + if (keyTransform) { + mapKey = keyTransform(mapKey); + } + + let expectedValue = values[value]; + if (valueTransform) { + expectedValue = valueTransform(expectedValue); + } + + const actualValue = map.get(mapKey); + + if (expectedValue instanceof Cell) { + expect(actualValue).toEqualCell(expectedValue); + } else if (expectedValue instanceof Address) { + expect(actualValue).toEqualAddress(expectedValue); + } else if (isSomeStruct(expectedValue)) { + expect(compareStructs(actualValue, expectedValue)).toBe( + true, + ); + } else { + expect(actualValue).toEqual(expectedValue); + } + }, + ); + + // Send the del operation + const delMessage: DelAllMaps = { + $$type: "DelAllMaps", + ...keys, + }; + + await contract.send( + treasury.getSender(), + { value: toNano("1") }, + delMessage, + ); + + // Retrieve all maps using `allMaps` getter to ensure they are deleted + const allMapsAfterDel = await contract.getAllMaps(); + + // Iterate over mapConfigs and assert maps are empty + mapConfigs.forEach(({ mapName }) => { + const map = allMapsAfterDel[mapName] as Dictionary; + expect(map.size).toBe(0); + }); + } + }); + + it("del: should delete multiple values", async () => { + // Set multiple values + for (const { keys, values } of testCases) { + const setMessage: SetAllMaps = { + $$type: "SetAllMaps", + ...keys, + ...values, + }; + await contract.send( + treasury.getSender(), + { value: toNano("1") }, + setMessage, + ); + } + + // Check that all maps are set + const allMapsBeforeDel = await contract.getAllMaps(); + mapConfigs.forEach(({ mapName }) => { + const map = allMapsBeforeDel[mapName] as Dictionary; + expect(map.size).toBe(testCases.length); + }); + + // Delete them + for (const { keys } of testCases) { + const delMessage: DelAllMaps = { $$type: "DelAllMaps", ...keys }; + await contract.send( + treasury.getSender(), + { value: toNano("1") }, + delMessage, + ); + } + + // Ensure maps are empty + const allMapsAfterDel = await contract.getAllMaps(); + mapConfigs.forEach(({ mapName }) => { + const map = allMapsAfterDel[mapName] as Dictionary; + expect(map.size).toBe(0); + }); + }); + + it("del: should not affect other keys when deleting", async () => { + // Set multiple values + for (const { keys, values } of testCases) { + const setMessage: SetAllMaps = { + $$type: "SetAllMaps", + ...keys, + ...values, + }; + await contract.send( + treasury.getSender(), + { value: toNano("1") }, + setMessage, + ); + } + + // Delete only the first test case's keys + const keysToDelete = testCases[0]!.keys; + const delMessage: DelAllMaps = { + $$type: "DelAllMaps", + ...keysToDelete, + }; + await contract.send( + treasury.getSender(), + { value: toNano("1") }, + delMessage, + ); + + // Check that only the deleted keys are removed + const allMapsAfterDel = await contract.getAllMaps(); + mapConfigs.forEach(({ mapName }) => { + const map = allMapsAfterDel[mapName] as Dictionary; + expect(map.size).toBe(testCases.length - 1); + }); + + // Verify other keys are unaffected + for (const { keys, values } of testCases.slice(1)) { + const getResponse = await contract.getAllMaps(); + + mapConfigs.forEach( + ({ mapName, key, value, keyTransform, valueTransform }) => { + const map = getResponse[mapName] as Dictionary; + + let mapKey = keys[key]; + if (keyTransform) { + mapKey = keyTransform(mapKey); + } + + let expectedValue = values[value]; + if (valueTransform) { + expectedValue = valueTransform(expectedValue); + } + + const actualValue = map.get(mapKey); + + if (expectedValue instanceof Cell) { + expect(actualValue).toEqualCell(expectedValue); + } else if (expectedValue instanceof Address) { + expect(actualValue).toEqualAddress(expectedValue); + } else if (isSomeStruct(expectedValue)) { + expect(compareStructs(actualValue, expectedValue)).toBe( + true, + ); + } else { + expect(actualValue).toEqual(expectedValue); + } + }, + ); + } + }); + + it("del: should do nothing when deleting non-existent keys", async () => { + // Set values except for the last test case + for (const { keys, values } of testCases.slice(0, -1)) { + const setMessage: SetAllMaps = { + $$type: "SetAllMaps", + ...keys, + ...values, + }; + await contract.send( + treasury.getSender(), + { value: toNano("1") }, + setMessage, + ); + } + + // Ensure existing data is unaffected + const allMapsBeforeDel = await contract.getAllMaps(); + mapConfigs.forEach(({ mapName }) => { + const map = allMapsBeforeDel[mapName] as Dictionary; + expect(map.size).toBe(testCases.length - 1); + }); + + // Attempt to delete non-existent keys + const nonExistentKeys = testCases[testCases.length - 1]!.keys; + const delMessage: DelAllMaps = { + $$type: "DelAllMaps", + ...nonExistentKeys, + }; + await contract.send( + treasury.getSender(), + { value: toNano("1") }, + delMessage, + ); + + // Ensure existing data is unaffected + const allMapsAfterDel = await contract.getAllMaps(); + mapConfigs.forEach(({ mapName }) => { + const map = allMapsAfterDel[mapName] as Dictionary; + expect(map.size).toBe(testCases.length - 1); + }); + + // Verify that the existing values are still there + for (const { keys, values } of testCases.slice(0, -1)) { + const allMaps = await contract.getAllMaps(); + + mapConfigs.forEach( + ({ mapName, key, value, keyTransform, valueTransform }) => { + const map = allMaps[mapName] as Dictionary; + + let mapKey = keys[key]; + if (keyTransform) { + mapKey = keyTransform(mapKey); + } + + let expectedValue = values[value]; + if (valueTransform) { + expectedValue = valueTransform(expectedValue); + } + + const actualValue = map.get(mapKey); + + if (expectedValue instanceof Cell) { + expect(actualValue).toEqualCell(expectedValue); + } else if (expectedValue instanceof Address) { + expect(actualValue).toEqualAddress(expectedValue); + } else if (isSomeStruct(expectedValue)) { + expect(compareStructs(actualValue, expectedValue)).toBe( + true, + ); + } else { + expect(actualValue).toEqual(expectedValue); + } + }, + ); + } + }); + + it("del: should handle delete after overwriting", async () => { + for (const { keys } of testCases) { + for (const { values } of testCases) { + // Set values + const setMessage: SetAllMaps = { + $$type: "SetAllMaps", + ...keys, + ...values, + }; await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "DelAddrMap5", key: addr }, + treasury.getSender(), + { value: toNano("1") }, + setMessage, ); + + // Delete values + const delMessage: DelAllMaps = { + $$type: "DelAllMaps", + ...keys, + }; await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "DelAddrMap6", key: addr }, + treasury.getSender(), + { value: toNano("1") }, + delMessage, ); + + // Ensure maps are empty + const allMapsAfterDel = await contract.getAllMaps(); + mapConfigs.forEach(({ mapName }) => { + const map = allMapsAfterDel[mapName] as Dictionary< + any, + any + >; + expect(map.size).toBe(0); + }); + } + } + }); + + it("exists: should return 'true' for existing keys and 'false' for non-existent keys", async () => { + // Set values for all test cases + for (const { keys, values } of testCases.slice(0, -1)) { + const setMessage: SetAllMaps = { + $$type: "SetAllMaps", + ...keys, + ...values, + }; + await contract.send( + treasury.getSender(), + { value: toNano("1") }, + setMessage, + ); + } + + // Check that all keys exist + for (const { keys } of testCases.slice(0, -1)) { + const existsResponse = await contract.getExistsAllMaps( + keys.keyInt, + keys.keyInt8, + keys.keyInt42, + keys.keyInt256, + keys.keyUint8, + keys.keyUint42, + keys.keyUint256, + keys.keyAddress, + ); + + Object.values(existsResponse).forEach((exists) => { + if (typeof exists === "boolean") { + expect(exists).toBe(true); + } + }); + } + + // Check that non-existent keys do not exist + const nonExistentKeys = testCases[testCases.length - 1]!.keys; + const nonExistentResponse = await contract.getExistsAllMaps( + nonExistentKeys.keyInt, + nonExistentKeys.keyInt8, + nonExistentKeys.keyInt42, + nonExistentKeys.keyInt256, + nonExistentKeys.keyUint8, + nonExistentKeys.keyUint42, + nonExistentKeys.keyUint256, + nonExistentKeys.keyAddress, + ); + + Object.values(nonExistentResponse).forEach((exists) => { + if (typeof exists === "boolean") { + expect(exists).toBe(false); + } + }); + }); + + it("exists: should still return 'true' after overwriting", async () => { + for (const { keys } of testCases) { + for (const { values } of testCases) { + // Send the set operation + const setMessage: SetAllMaps = { + $$type: "SetAllMaps", + ...keys, + ...values, + }; + await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "DelAddrMap7", key: addr }, + treasury.getSender(), + { value: toNano("1") }, + setMessage, ); - // Check value cleared - expect(await contract.getIntMap1Value(k)).toBeNull(); - expect(await contract.getIntMap2Value(k)).toBeNull(); - expect(await contract.getIntMap3Value(k)).toBeNull(); - expect(await contract.getIntMap4Value(k)).toBeNull(); - expect(await contract.getIntMap5Value(k)).toBeNull(); - expect(await contract.getIntMap6_1Value(keySmall)).toBe(null); - expect(await contract.getIntMap6_2Value(keySmall)).toBe(null); - expect(await contract.getIntMap6_3Value(keySmall)).toBe(null); - expect(await contract.getIntMap6_4Value(keySmall)).toBe(null); - expect(await contract.getIntMap6_5Value(keySmall)).toBe(null); - expect(await contract.getIntMap6_6Value(keySmall)).toBe(null); - expect(await contract.getIntMap6_7Value(keySmall)).toBe(null); - expect(await contract.getIntMap7_1Value(keySmallAbs)).toBe( - null, - ); - expect(await contract.getIntMap7_2Value(keySmallAbs)).toBe( - null, - ); - expect(await contract.getIntMap7_3Value(keySmallAbs)).toBe( - null, - ); - expect(await contract.getIntMap7_4Value(keySmallAbs)).toBe( - null, - ); - expect(await contract.getIntMap7_5Value(keySmallAbs)).toBe( - null, - ); - expect(await contract.getIntMap7_6Value(keySmallAbs)).toBe( - null, - ); - expect(await contract.getIntMap8_1Value(k)).toBe(null); - expect(await contract.getIntMap8_2Value(k)).toBe(null); - expect(await contract.getIntMap8_3Value(k)).toBe(null); - expect(await contract.getIntMap8_4Value(k)).toBe(null); - expect(await contract.getIntMap8_5Value(k)).toBe(null); - expect(await contract.getIntMap8_6Value(k)).toBe(null); - expect(await contract.getIntMap8_7Value(k)).toBe(null); - expect(await contract.getIntMap9_1Value(k)).toBe(null); - expect(await contract.getIntMap9_2Value(k)).toBe(null); - expect(await contract.getIntMap9_3Value(k)).toBe(null); - expect(await contract.getIntMap9_4Value(k)).toBe(null); - expect(await contract.getIntMap9_5Value(k)).toBe(null); - expect(await contract.getIntMap9_6Value(k)).toBe(null); - expect(await contract.getIntMap10_1Value(keySmallAbs)).toBe( - null, - ); - expect(await contract.getIntMap10_2Value(keySmallAbs)).toBe( - null, - ); - expect(await contract.getIntMap10_3Value(keySmallAbs)).toBe( - null, - ); - expect(await contract.getIntMap10_4Value(keySmallAbs)).toBe( - null, + // Call the .exists operation on all maps + const existsResponse = await contract.getExistsAllMaps( + keys.keyInt, + keys.keyInt8, + keys.keyInt42, + keys.keyInt256, + keys.keyUint8, + keys.keyUint42, + keys.keyUint256, + keys.keyAddress, ); - expect(await contract.getAddrMap1Value(addr)).toBeNull(); - expect(await contract.getAddrMap2Value(addr)).toBeNull(); - expect(await contract.getAddrMap3Value(addr)).toBeNull(); - expect(await contract.getAddrMap4Value(addr)).toBeNull(); - expect(await contract.getAddrMap5Value(addr)).toBeNull(); - expect(await contract.getAddrMap6_1Value(addr)).toBe(null); - expect(await contract.getAddrMap6_2Value(addr)).toBe(null); - expect(await contract.getAddrMap6_3Value(addr)).toBe(null); - expect(await contract.getAddrMap6_4Value(addr)).toBe(null); - expect(await contract.getAddrMap6_5Value(addr)).toBe(null); - expect(await contract.getAddrMap6_6Value(addr)).toBe(null); - expect(await contract.getAddrMap6_7Value(addr)).toBe(null); - expect(await contract.getAddrMap7_1Value(addr)).toBe(null); - expect(await contract.getAddrMap7_2Value(addr)).toBe(null); - expect(await contract.getAddrMap7_3Value(addr)).toBe(null); - expect(await contract.getAddrMap7_4Value(addr)).toBe(null); - expect(await contract.getAddrMap7_5Value(addr)).toBe(null); - expect(await contract.getAddrMap7_6Value(addr)).toBe(null); - } - } catch (e) { - if (e instanceof ComputeError) { - if (e.logs) { - console.warn(e.logs); - } + + Object.values(existsResponse).forEach((exists) => { + if (typeof exists === "boolean") { + expect(exists).toBe(true); + } + }); } - throw e; } }); - it("should implement map.exists correctly", async () => { - jest.setTimeout(2 * 60000); - try { - // Initial state - expect(await contract.getIntMap1Exists(1n)).toBe(false); - expect(await contract.getIntMap2Exists(1n)).toBe(false); - expect(await contract.getIntMap3Exists(1n)).toBe(false); - expect(await contract.getIntMap4Exists(1n)).toBe(false); - expect( - await contract.getAddrMap1Exists(randomAddress(0, "addr-1")), - ).toBe(false); - expect( - await contract.getAddrMap2Exists(randomAddress(0, "addr-1")), - ).toBe(false); - expect( - await contract.getAddrMap3Exists(randomAddress(0, "addr-1")), - ).toBe(false); - expect( - await contract.getAddrMap4Exists(randomAddress(0, "addr-1")), - ).toBe(false); - - // Set keys - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetIntMap1", key: 1n, value: 1n }, - ); + it("exists: should return 'false' for all keys after clearing all maps", async () => { + for (const { keys, values } of testCases) { + const setMessage: SetAllMaps = { + $$type: "SetAllMaps", + ...keys, + ...values, + }; await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetIntMap2", key: 1n, value: true }, + treasury.getSender(), + { value: toNano("1") }, + setMessage, ); + } + + for (const { keys } of testCases) { + const clearMessage: SetAllMaps = { + $$type: "SetAllMaps", + ...keys, + valueInt: null, + valueInt8: null, + valueInt42: null, + valueInt256: null, + valueUint8: null, + valueUint42: null, + valueUint256: null, + valueBool: null, + valueCell: null, + valueAddress: null, + valueStruct: null, + }; await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { - $$type: "SetIntMap3", - key: 1n, - value: beginCell().storeUint(123123, 128).endCell(), - }, + treasury.getSender(), + { value: toNano("1") }, + clearMessage, ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { - $$type: "SetIntMap4", - key: 1n, - value: { $$type: "SomeStruct", value: 10012312n }, - }, + } + + for (const { keys } of testCases) { + const existsResponse = await contract.getExistsAllMaps( + keys.keyInt, + keys.keyInt8, + keys.keyInt42, + keys.keyInt256, + keys.keyUint8, + keys.keyUint42, + keys.keyUint256, + keys.keyAddress, ); - const addr = randomAddress(0, "addr-1"); + + Object.values(existsResponse).forEach((exists) => { + if (typeof exists === "boolean") { + expect(exists).toBe(false); + } + }); + } + }); + + it("isEmpty: should return 'true' for empty maps and 'false' for non-empty maps", async () => { + for (const { keys, values } of testCases) { + // Check that all maps are empty initially + const initialIsEmptyResponse = await contract.getIsEmptyAllMaps(); + Object.values(initialIsEmptyResponse).forEach((isEmpty) => { + if (typeof isEmpty === "boolean") { + expect(isEmpty).toBe(true); + } + }); + + // Set values for the current test case + const setMessage: SetAllMaps = { + $$type: "SetAllMaps", + ...keys, + ...values, + }; await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetAddrMap1", key: addr, value: 1n }, + treasury.getSender(), + { value: toNano("1") }, + setMessage, ); + + // Check that all maps are non-empty + const nonEmptyIsEmptyResponse = await contract.getIsEmptyAllMaps(); + Object.values(nonEmptyIsEmptyResponse).forEach((isEmpty) => { + if (typeof isEmpty === "boolean") { + expect(isEmpty).toBe(false); + } + }); + + // Clear all maps + for (const { keys } of testCases) { + const clearMessage: SetAllMaps = { + $$type: "SetAllMaps", + ...keys, + valueInt: null, + valueInt8: null, + valueInt42: null, + valueInt256: null, + valueUint8: null, + valueUint42: null, + valueUint256: null, + valueBool: null, + valueCell: null, + valueAddress: null, + valueStruct: null, + }; + await contract.send( + treasury.getSender(), + { value: toNano("1") }, + clearMessage, + ); + } + + // Check that all maps are empty again + const emptyIsEmptyResponse = await contract.getIsEmptyAllMaps(); + Object.values(emptyIsEmptyResponse).forEach((isEmpty) => { + if (typeof isEmpty === "boolean") { + expect(isEmpty).toBe(true); + } + }); + } + }); + + it("asCell: should correctly serialize and deserialize maps", async () => { + for (const { keys, values } of testCases) { + // Set values for the current test case + const setMessage: SetAllMaps = { + $$type: "SetAllMaps", + ...keys, + ...values, + }; await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetAddrMap2", key: addr, value: true }, + treasury.getSender(), + { value: toNano("1") }, + setMessage, ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { - $$type: "SetAddrMap3", - key: addr, - value: beginCell().storeUint(123123, 128).endCell(), + + // Serialize all maps to a Cell + const cellResponse = await contract.getAsCellAllMaps(); + + // Retrieve all maps using `allMaps` getter + const allMaps = await contract.getAllMaps(); + + // Iterate over mapConfigs and perform assertions + mapConfigs.forEach( + ({ mapName, key, value, keyTransform, valueTransform }) => { + const map = allMaps[mapName] as Dictionary; + + expect(map.size).toBe(1); + + let mapKey = keys[key]; + if (keyTransform) { + mapKey = keyTransform(mapKey); + } + + let expectedValue = values[value]; + if (valueTransform) { + expectedValue = valueTransform(expectedValue); + } + + const actualValue = map.get(mapKey); + + if (expectedValue instanceof Cell) { + expect(actualValue).toEqualCell(expectedValue); + } else if (expectedValue instanceof Address) { + expect(actualValue).toEqualAddress(expectedValue); + } else if (isSomeStruct(expectedValue)) { + expect(compareStructs(actualValue, expectedValue)).toBe( + true, + ); + } else { + expect(actualValue).toEqual(expectedValue); + } + + // Serialize the map from allMaps to a Cell to compare with the response + const serializedMap = beginCell() + .storeDictDirect(map) + .endCell(); + + expect(cellResponse[mapName]).toEqualCell(serializedMap); }, ); + + // Clear all maps + for (const { keys } of testCases) { + const clearMessage: SetAllMaps = { + $$type: "SetAllMaps", + ...keys, + valueInt: null, + valueInt8: null, + valueInt42: null, + valueInt256: null, + valueUint8: null, + valueUint42: null, + valueUint256: null, + valueBool: null, + valueCell: null, + valueAddress: null, + valueStruct: null, + }; + await contract.send( + treasury.getSender(), + { value: toNano("1") }, + clearMessage, + ); + } + } + }); + + it("replace: should replace values and clear them", async () => { + for (const { keys } of testCases) { + // Send the set operation + const setMessage: SetAllMaps = { + $$type: "SetAllMaps", + ...keys, + ...testCases[0]!.values, + }; + await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { - $$type: "SetAddrMap4", - key: addr, - value: { $$type: "SomeStruct", value: 10012312n }, - }, + treasury.getSender(), + { value: toNano("1") }, + setMessage, ); - // Check exists - expect(await contract.getIntMap1Exists(1n)).toBe(true); - expect(await contract.getIntMap2Exists(1n)).toBe(true); - expect(await contract.getIntMap3Exists(1n)).toBe(true); - expect(await contract.getIntMap4Exists(1n)).toBe(true); - expect(await contract.getAddrMap1Exists(addr)).toBe(true); - expect(await contract.getAddrMap2Exists(addr)).toBe(true); - expect(await contract.getAddrMap3Exists(addr)).toBe(true); - expect(await contract.getAddrMap4Exists(addr)).toBe(true); - - // Clear keys + for (const { values } of testCases) { + // Send the replace operation + const replaceMessage: ReplaceAllMaps = { + $$type: "ReplaceAllMaps", + ...keys, + ...values, + }; + + await contract.send( + treasury.getSender(), + { value: toNano("1") }, + replaceMessage, + ); + + // Retrieve all maps using `allMaps` getter + const allMaps = await contract.getAllMaps(); + + // Iterate over mapConfigs and perform assertions + mapConfigs.forEach( + ({ mapName, key, value, keyTransform, valueTransform }) => { + const map = allMaps[mapName] as Dictionary; + + expect(map.size).toBe(1); + + let mapKey = keys[key]; + if (keyTransform) { + mapKey = keyTransform(mapKey); + } + + let expectedValue = values[value]; + if (valueTransform) { + expectedValue = valueTransform(expectedValue); + } + + const actualValue = map.get(mapKey); + + if (expectedValue instanceof Cell) { + expect(actualValue).toEqualCell(expectedValue); + } else if (expectedValue instanceof Address) { + expect(actualValue).toEqualAddress(expectedValue); + } else if (isSomeStruct(expectedValue)) { + expect( + compareStructs(actualValue, expectedValue), + ).toBe(true); + } else { + expect(actualValue).toEqual(expectedValue); + } + }, + ); + } + + // Clear all maps + for (const { keys } of testCases) { + const clearMessage: ReplaceAllMaps = { + $$type: "ReplaceAllMaps", + ...keys, + valueInt: null, + valueInt8: null, + valueInt42: null, + valueInt256: null, + valueUint8: null, + valueUint42: null, + valueUint256: null, + valueBool: null, + valueCell: null, + valueAddress: null, + valueStruct: null, + }; + await contract.send( + treasury.getSender(), + { value: toNano("1") }, + clearMessage, + ); + } + } + + // Check that all maps are empty again + const allMaps = await contract.getAllMaps(); + mapConfigs.forEach(({ mapName }) => { + const map = allMaps[mapName] as Dictionary; + expect(map.size).toBe(0); + }); + }); + + it("replace: should not replace values when keys do not exist", async () => { + for (const { keys, values } of testCases) { + // Send the replace operation + const replaceMessage: ReplaceAllMaps = { + $$type: "ReplaceAllMaps", + ...keys, + ...values, + }; + await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetIntMap1", key: 1n, value: null }, + treasury.getSender(), + { value: toNano("1") }, + replaceMessage, ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetIntMap2", key: 1n, value: null }, + + // Retrieve all maps using `allMaps` getter + const allMaps = await contract.getAllMaps(); + + // Check that all maps are still empty + mapConfigs.forEach(({ mapName }) => { + const map = allMaps[mapName] as Dictionary; + expect(map.size).toBe(0); + }); + } + }); + + it("replace: should return 'true' when replacing values and 'false' when keys do not exist", async () => { + for (const { keys, values } of testCases) { + // Call the .replace operation on all maps + const replaceResult = await contract.getReplaceAllMaps( + keys.keyInt, + keys.keyInt8, + keys.keyInt42, + keys.keyInt256, + keys.keyUint8, + keys.keyUint42, + keys.keyUint256, + keys.keyAddress, + values.valueInt, + values.valueInt8, + values.valueInt42, + values.valueInt256, + values.valueUint8, + values.valueUint42, + values.valueUint256, + values.valueBool, + values.valueCell, + values.valueAddress, + values.valueStruct, ); + + // Check that all return values are 'false' + Object.values(replaceResult).forEach((result) => { + if (typeof result === "boolean") { + expect(result).toBe(false); + } + }); + + // Send the set operation + const setMessage: SetAllMaps = { + $$type: "SetAllMaps", + ...keys, + ...values, + }; + await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetIntMap3", key: 1n, value: null }, + treasury.getSender(), + { value: toNano("1") }, + setMessage, ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetIntMap4", key: 1n, value: null }, + + // Call the .replace operation on all maps + const replaceResultAfterSet = await contract.getReplaceAllMaps( + keys.keyInt, + keys.keyInt8, + keys.keyInt42, + keys.keyInt256, + keys.keyUint8, + keys.keyUint42, + keys.keyUint256, + keys.keyAddress, + values.valueInt, + values.valueInt8, + values.valueInt42, + values.valueInt256, + values.valueUint8, + values.valueUint42, + values.valueUint256, + values.valueBool, + values.valueCell, + values.valueAddress, + values.valueStruct, ); + + // Check that all return values are 'true' + Object.values(replaceResultAfterSet).forEach((result) => { + if (typeof result === "boolean") { + expect(result).toBe(true); + } + }); + } + }); + + it("replaceGet: should replace values and clear them", async () => { + for (const { keys } of testCases) { + // Send the set operation + const setMessage: SetAllMaps = { + $$type: "SetAllMaps", + ...keys, + ...testCases[0]!.values, + }; + await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetAddrMap1", key: addr, value: null }, + treasury.getSender(), + { value: toNano("1") }, + setMessage, ); + + for (const { values } of testCases) { + // Send the replace operation + const replaceGetMessage: ReplaceGetAllMaps = { + $$type: "ReplaceGetAllMaps", + ...keys, + ...values, + }; + + await contract.send( + treasury.getSender(), + { value: toNano("1") }, + replaceGetMessage, + ); + + // Retrieve all maps using `allMaps` getter + const allMaps = await contract.getAllMaps(); + + // Iterate over mapConfigs and perform assertions + mapConfigs.forEach( + ({ mapName, key, value, keyTransform, valueTransform }) => { + const map = allMaps[mapName] as Dictionary; + + expect(map.size).toBe(1); + + let mapKey = keys[key]; + if (keyTransform) { + mapKey = keyTransform(mapKey); + } + + let expectedValue = values[value]; + if (valueTransform) { + expectedValue = valueTransform(expectedValue); + } + + const actualValue = map.get(mapKey); + + if (expectedValue instanceof Cell) { + expect(actualValue).toEqualCell(expectedValue); + } else if (expectedValue instanceof Address) { + expect(actualValue).toEqualAddress(expectedValue); + } else if (isSomeStruct(expectedValue)) { + expect( + compareStructs(actualValue, expectedValue), + ).toBe(true); + } else { + expect(actualValue).toEqual(expectedValue); + } + }, + ); + } + + // Clear all maps + for (const { keys } of testCases) { + const clearMessage: ReplaceGetAllMaps = { + $$type: "ReplaceGetAllMaps", + ...keys, + valueInt: null, + valueInt8: null, + valueInt42: null, + valueInt256: null, + valueUint8: null, + valueUint42: null, + valueUint256: null, + valueBool: null, + valueCell: null, + valueAddress: null, + valueStruct: null, + }; + await contract.send( + treasury.getSender(), + { value: toNano("1") }, + clearMessage, + ); + } + } + + // Check that all maps are empty again + const allMaps = await contract.getAllMaps(); + mapConfigs.forEach(({ mapName }) => { + const map = allMaps[mapName] as Dictionary; + expect(map.size).toBe(0); + }); + }); + + it("replaceGet: should not replace values when keys do not exist", async () => { + for (const { keys, values } of testCases) { + // Send the replace operation + const replaceGetMessage: ReplaceGetAllMaps = { + $$type: "ReplaceGetAllMaps", + ...keys, + ...values, + }; + await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetAddrMap2", key: addr, value: null }, + treasury.getSender(), + { value: toNano("1") }, + replaceGetMessage, ); - await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetAddrMap3", key: addr, value: null }, + + // Retrieve all maps using `allMaps` getter + const allMaps = await contract.getAllMaps(); + + // Check that all maps are still empty + mapConfigs.forEach(({ mapName }) => { + const map = allMaps[mapName] as Dictionary; + expect(map.size).toBe(0); + }); + } + }); + + it("replaceGet: should return old values when replaced and null when keys do not exist", async () => { + for (const { keys, values } of testCases) { + // Call the .replace operation on all maps + const replaceGetResult = await contract.getReplaceGetAllMaps( + keys.keyInt, + keys.keyInt8, + keys.keyInt42, + keys.keyInt256, + keys.keyUint8, + keys.keyUint42, + keys.keyUint256, + keys.keyAddress, + values.valueInt, + values.valueInt8, + values.valueInt42, + values.valueInt256, + values.valueUint8, + values.valueUint42, + values.valueUint256, + values.valueBool, + values.valueCell, + values.valueAddress, + values.valueStruct, ); + + // Check that all return values are 'null' + Object.values(replaceGetResult).forEach((result) => { + if (result !== "ReplaceGetAllMapsResult") { + expect(result).toBeNull(); + } + }); + + // Send the set operation + const setMessage: SetAllMaps = { + $$type: "SetAllMaps", + ...keys, + ...values, + }; + await contract.send( - treasure.getSender(), - { value: toNano(1) }, - { $$type: "SetAddrMap4", key: addr, value: null }, + treasury.getSender(), + { value: toNano("1") }, + setMessage, ); - // Check exists - expect(await contract.getIntMap1Exists(1n)).toBe(false); - expect(await contract.getIntMap2Exists(1n)).toBe(false); - expect(await contract.getIntMap3Exists(1n)).toBe(false); - expect(await contract.getIntMap4Exists(1n)).toBe(false); - expect(await contract.getAddrMap1Exists(addr)).toBe(false); - expect(await contract.getAddrMap2Exists(addr)).toBe(false); - expect(await contract.getAddrMap3Exists(addr)).toBe(false); - expect(await contract.getAddrMap4Exists(addr)).toBe(false); - } catch (e) { - if (e instanceof ComputeError) { - if (e.logs) { - console.warn(e.logs); + // Call the .replace operation on all maps + const replaceGetResultAfterSet = + await contract.getReplaceGetAllMaps( + keys.keyInt, + keys.keyInt8, + keys.keyInt42, + keys.keyInt256, + keys.keyUint8, + keys.keyUint42, + keys.keyUint256, + keys.keyAddress, + values.valueInt, + values.valueInt8, + values.valueInt42, + values.valueInt256, + values.valueUint8, + values.valueUint42, + values.valueUint256, + values.valueBool, + values.valueCell, + values.valueAddress, + values.valueStruct, + ); + + // Check that all return values are equal to the old values + mapConfigs.forEach(({ mapName, value, valueTransform }) => { + let expectedValue = values[value]; + let actualValue = replaceGetResultAfterSet[mapName]; + if (valueTransform) { + expectedValue = valueTransform(expectedValue); + actualValue = valueTransform(actualValue); } - } - throw e; + + if (expectedValue instanceof Cell) { + expect(actualValue).toEqualCell(expectedValue); + } else if (expectedValue instanceof Address) { + expect(actualValue).toEqualAddress(expectedValue); + } else if (isSomeStruct(expectedValue)) { + expect( + compareStructs( + actualValue as SomeStruct, + expectedValue, + ), + ).toBe(true); + } else { + expect(actualValue).toEqual(expectedValue); + } + }); } }); + + it("checkNullReference: should throw an error in getter when accessing a null reference", async () => { + await expect(contract.getCheckNullReference()).rejects.toThrow(); + }); + + it("checkNullReference: should throw an error in receiver when accessing a null reference", async () => { + const result = await contract.send( + treasury.getSender(), + { value: toNano("1") }, + { + $$type: "CheckNullReference", + }, + ); + + expect(result.transactions).toHaveLength(3); + expect(result.transactions).toHaveTransaction({ + on: contract.address, + success: false, + exitCode: 128, + }); + }); }); diff --git a/stdlib/stdlib.fc b/stdlib/stdlib.fc index ac05cbc7c..91d461649 100644 --- a/stdlib/stdlib.fc +++ b/stdlib/stdlib.fc @@ -544,6 +544,10 @@ cell idict_get_ref(cell dict, int key_len, int index) asm(index dict key_len) "D (cell, slice, int) udict_delete_get?(cell dict, int key_len, int index) asm(index dict key_len) "DICTUDELGET" "NULLSWAPIFNOT"; (cell, (slice, int)) ~idict_delete_get?(cell dict, int key_len, int index) asm(index dict key_len) "DICTIDELGET" "NULLSWAPIFNOT"; (cell, (slice, int)) ~udict_delete_get?(cell dict, int key_len, int index) asm(index dict key_len) "DICTUDELGET" "NULLSWAPIFNOT"; +(cell, cell, int) idict_delete_get_ref?(cell dict, int key_len, int index) asm(index dict key_len) "DICTIDELGETREF" "NULLSWAPIFNOT"; +(cell, cell, int) udict_delete_get_ref?(cell dict, int key_len, int index) asm(index dict key_len) "DICTUDELGETREF" "NULLSWAPIFNOT"; +(cell, (cell, int)) ~idict_delete_get_ref?(cell dict, int key_len, int index) asm(index dict key_len) "DICTIDELGETREF" "NULLSWAPIFNOT"; +(cell, (cell, int)) ~udict_delete_get_ref?(cell dict, int key_len, int index) asm(index dict key_len) "DICTUDELGETREF" "NULLSWAPIFNOT"; cell udict_set(cell dict, int key_len, int index, slice value) asm(value index dict key_len) "DICTUSET"; (cell, ()) ~udict_set(cell dict, int key_len, int index, slice value) asm(value index dict key_len) "DICTUSET"; cell idict_set(cell dict, int key_len, int index, slice value) asm(value index dict key_len) "DICTISET"; @@ -552,18 +556,37 @@ cell dict_set(cell dict, int key_len, slice index, slice value) asm(value index (cell, ()) ~dict_set(cell dict, int key_len, slice index, slice value) asm(value index dict key_len) "DICTSET"; (cell, int) udict_add?(cell dict, int key_len, int index, slice value) asm(value index dict key_len) "DICTUADD"; (cell, int) udict_replace?(cell dict, int key_len, int index, slice value) asm(value index dict key_len) "DICTUREPLACE"; +(cell, int) udict_replace_ref?(cell dict, int key_len, int index, cell value) asm(value index dict key_len) "DICTUREPLACEREF"; +(cell, slice, int) udict_replaceget?(cell dict, int key_len, int index, slice value) asm(value index dict key_len) "DICTUREPLACEGET" "NULLSWAPIFNOT"; +(cell, cell, int) udict_replaceget_ref?(cell dict, int key_len, int index, cell value) asm(value index dict key_len) "DICTUREPLACEGETREF" "NULLSWAPIFNOT"; +(cell, (slice, int)) ~udict_replaceget?(cell dict, int key_len, int index, slice value) asm(value index dict key_len) "DICTUREPLACEGET" "NULLSWAPIFNOT"; +(cell, (cell, int)) ~udict_replaceget_ref?(cell dict, int key_len, int index, cell value) asm(value index dict key_len) "DICTUREPLACEGETREF" "NULLSWAPIFNOT"; (cell, int) idict_add?(cell dict, int key_len, int index, slice value) asm(value index dict key_len) "DICTIADD"; (cell, int) idict_replace?(cell dict, int key_len, int index, slice value) asm(value index dict key_len) "DICTIREPLACE"; +(cell, int) idict_replace_ref?(cell dict, int key_len, int index, cell value) asm(value index dict key_len) "DICTIREPLACEREF"; +(cell, slice, int) idict_replaceget?(cell dict, int key_len, int index, slice value) asm(value index dict key_len) "DICTIREPLACEGET" "NULLSWAPIFNOT"; +(cell, cell, int) idict_replaceget_ref?(cell dict, int key_len, int index, cell value) asm(value index dict key_len) "DICTIREPLACEGETREF" "NULLSWAPIFNOT"; +(cell, (slice, int)) ~idict_replaceget?(cell dict, int key_len, int index, slice value) asm(value index dict key_len) "DICTIREPLACEGET" "NULLSWAPIFNOT"; +(cell, (cell, int)) ~idict_replaceget_ref?(cell dict, int key_len, int index, cell value) asm(value index dict key_len) "DICTIREPLACEGETREF" "NULLSWAPIFNOT"; cell udict_set_builder(cell dict, int key_len, int index, builder value) asm(value index dict key_len) "DICTUSETB"; (cell, ()) ~udict_set_builder(cell dict, int key_len, int index, builder value) asm(value index dict key_len) "DICTUSETB"; cell idict_set_builder(cell dict, int key_len, int index, builder value) asm(value index dict key_len) "DICTISETB"; (cell, ()) ~idict_set_builder(cell dict, int key_len, int index, builder value) asm(value index dict key_len) "DICTISETB"; cell dict_set_builder(cell dict, int key_len, slice index, builder value) asm(value index dict key_len) "DICTSETB"; (cell, ()) ~dict_set_builder(cell dict, int key_len, slice index, builder value) asm(value index dict key_len) "DICTSETB"; +(cell, int) dict_replace_builder?(cell dict, int key_len, slice index, builder value) asm(value index dict key_len) "DICTREPLACEB"; +(cell, builder, int) dict_replaceget_builder?(cell dict, int key_len, slice index, builder value) asm(value index dict key_len) "DICTREPLACEGETB" "NULLSWAPIFNOT"; +(cell, slice, int) dict_replaceget?(cell dict, int key_len, slice index, slice value) asm(value index dict key_len) "DICTREPLACEGET" "NULLSWAPIFNOT"; +(cell, (builder, int)) ~dict_replaceget_builder?(cell dict, int key_len, slice index, builder value) asm(value index dict key_len) "DICTREPLACEGETB" "NULLSWAPIFNOT"; +(cell, (slice, int)) ~dict_replaceget?(cell dict, int key_len, slice index, slice value) asm(value index dict key_len) "DICTREPLACEGET" "NULLSWAPIFNOT"; (cell, int) udict_add_builder?(cell dict, int key_len, int index, builder value) asm(value index dict key_len) "DICTUADDB"; (cell, int) udict_replace_builder?(cell dict, int key_len, int index, builder value) asm(value index dict key_len) "DICTUREPLACEB"; +(cell, builder, int) udict_replaceget_builder?(cell dict, int key_len, int index, builder value) asm(value index dict key_len) "DICTUREPLACEGETB" "NULLSWAPIFNOT"; +(cell, (builder, int)) ~udict_replaceget_builder?(cell dict, int key_len, int index, builder value) asm(value index dict key_len) "DICTUREPLACEGETB" "NULLSWAPIFNOT"; (cell, int) idict_add_builder?(cell dict, int key_len, int index, builder value) asm(value index dict key_len) "DICTIADDB"; (cell, int) idict_replace_builder?(cell dict, int key_len, int index, builder value) asm(value index dict key_len) "DICTIREPLACEB"; +(cell, builder, int) idict_replaceget_builder?(cell dict, int key_len, int index, builder value) asm(value index dict key_len) "DICTIREPLACEGETB" "NULLSWAPIFNOT"; +(cell, (builder, int)) ~idict_replaceget_builder?(cell dict, int key_len, int index, builder value) asm(value index dict key_len) "DICTIREPLACEGETB" "NULLSWAPIFNOT"; (cell, int, slice, int) udict_delete_get_min(cell dict, int key_len) asm(-> 0 2 1 3) "DICTUREMMIN" "NULLSWAPIFNOT2"; (cell, (int, slice, int)) ~udict::delete_get_min(cell dict, int key_len) asm(-> 0 2 1 3) "DICTUREMMIN" "NULLSWAPIFNOT2"; (cell, int, slice, int) idict_delete_get_min(cell dict, int key_len) asm(-> 0 2 1 3) "DICTIREMMIN" "NULLSWAPIFNOT2";