From 4875f2a361b142a7f6ca1b663efd9026db6223b2 Mon Sep 17 00:00:00 2001 From: arobsn Date: Fri, 21 Jul 2023 15:58:33 -0300 Subject: [PATCH] compiler: Set `ErgoTree` v1 as default output. --- .changeset/config.json | 3 +- .changeset/seven-zoos-own.md | 5 ++ packages/compiler/package.json | 2 +- packages/compiler/src/compiler.spec.ts | 87 ++++++++++++++++++-------- packages/compiler/src/compiler.ts | 63 +++++++++++++------ 5 files changed, 113 insertions(+), 47 deletions(-) create mode 100644 .changeset/seven-zoos-own.md diff --git a/.changeset/config.json b/.changeset/config.json index 76d553fb..ca1c5558 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -6,6 +6,5 @@ "linked": [], "access": "public", "baseBranch": "master", - "updateInternalDependencies": "patch", - "ignore": ["@fleet-sdk/compiler"] + "updateInternalDependencies": "patch" } diff --git a/.changeset/seven-zoos-own.md b/.changeset/seven-zoos-own.md new file mode 100644 index 00000000..e04fb10a --- /dev/null +++ b/.changeset/seven-zoos-own.md @@ -0,0 +1,5 @@ +--- +"@fleet-sdk/compiler": minor +--- + +Set `ErgoTree` v1 as default output. diff --git a/packages/compiler/package.json b/packages/compiler/package.json index be18e22d..413b2a6b 100644 --- a/packages/compiler/package.json +++ b/packages/compiler/package.json @@ -1,6 +1,6 @@ { "name": "@fleet-sdk/compiler", - "version": "0.1.0-alpha.0", + "version": "0.0.0", "description": "Sigma.JS powered ErgoScript compiler.", "main": "dist/cjs/index.js", "module": "dist/esm/index.js", diff --git a/packages/compiler/src/compiler.spec.ts b/packages/compiler/src/compiler.spec.ts index 1a6a3ec9..c4d052b0 100644 --- a/packages/compiler/src/compiler.spec.ts +++ b/packages/compiler/src/compiler.spec.ts @@ -1,39 +1,66 @@ -import { Network } from "@fleet-sdk/common"; import { SInt } from "@fleet-sdk/core"; import { HexString, Value, ValueObj } from "sigmastate-js/main"; import { describe, expect, it, test } from "vitest"; -import { compile, parseNamedConstantsMap } from "./compiler"; - -const compilerTestVectors = [ +import { compile, compilerDefaults, CompilerOptions, parseNamedConstantsMap } from "./compiler"; + +const compilerTestVectors: { + name: string; + script: string; + tree: string; + options: CompilerOptions; +}[] = [ { - name: "Segregated constants", + name: "v0 - Segregated constants", script: "sigmaProp(HEIGHT > 100)", tree: "100104c801d191a37300", - options: { segregateConstants: true, includeSize: false, map: undefined } + options: { version: 0, segregateConstants: true, includeSize: false } }, { - name: "Embedded constants", + name: "v0 - Embedded constants", script: "sigmaProp(HEIGHT > 100)", tree: "00d191a304c801", - options: { segregateConstants: false, includeSize: false, map: undefined } + options: { version: 0, segregateConstants: false, includeSize: false } }, { - name: "Tree size included", + name: "v0 - Tree size included", script: "sigmaProp(HEIGHT > 100)", tree: "0806d191a304c801", - options: { segregateConstants: false, includeSize: true, map: undefined } + options: { version: 0, segregateConstants: false, includeSize: true } }, { - name: "Tree size included and constant segregated", + name: "v0 - Tree size included and constant segregated", script: "sigmaProp(HEIGHT > 100)", tree: "18090104c801d191a37300", - options: { segregateConstants: true, includeSize: true, map: undefined } + options: { version: 0, segregateConstants: true, includeSize: true } }, { - name: "Named constants", + name: "v0 - Named constants", script: "sigmaProp(HEIGHT > deadline)", tree: "100104c801d191a37300", - options: { segregateConstants: true, includeSize: false, map: { deadline: SInt(100) } } + options: { + version: 0, + segregateConstants: true, + includeSize: false, + map: { deadline: SInt(100) } + } + }, + { + name: "v1 - Segregated constants", + script: "sigmaProp(HEIGHT > 100)", + tree: "19090104c801d191a37300", + options: { version: 1, segregateConstants: true } + }, + { + name: "v1 - Embedded constants", + script: "sigmaProp(HEIGHT > 100)", + tree: "0906d191a304c801", + options: { version: 1, segregateConstants: false } + }, + { + name: "v1 - Named constants", + script: "sigmaProp(HEIGHT > deadline)", + tree: "19090104c801d191a37300", + options: { version: 1, segregateConstants: true, map: { deadline: SInt(100) } } } ]; @@ -43,7 +70,13 @@ describe("ErgoScript Compiler", () => { expect(tree.toHex()).to.be.equal(tv.tree); expect(tree.hasSegregatedConstants).to.be.equal(tv.options.segregateConstants); - expect(tree.hasSize).to.be.equal(tv.options.includeSize); + expect(tree.version).to.be.equal(tv.options.version); + + if (tv.options.version === 1) { + expect(tree.hasSize).to.be.true; + } else if (tv.options.version === 0) { + expect(tree.hasSize).to.be.equal(tv.options.includeSize); + } if (tv.options.segregateConstants) { expect(tree.constants).not.to.be.empty; @@ -53,19 +86,23 @@ describe("ErgoScript Compiler", () => { }); it("Should use default if not compiler options is set", () => { - const tree = compile("sigmaProp(HEIGHT > 100)"); + const { version, segregateConstants } = compilerDefaults; - expect(tree.toHex()).to.be.equal("18090104c801d191a37300"); - expect(tree.hasSegregatedConstants).to.be.equal(true); - expect(tree.hasSize).to.be.equal(true); + const tree = compile("sigmaProp(HEIGHT > 100)"); + expect(tree.toHex()).to.be.equal("19090104c801d191a37300"); + expect(tree.hasSegregatedConstants).to.be.equal(segregateConstants); + expect(tree.version).to.be.equal(version); + expect(tree.hasSize).to.be.equal( + version > 0 || (version === 0 && compilerDefaults.includeSize) + ); }); - it("Should compile for testnet", () => { - const tree = compile("sigmaProp(HEIGHT > 100)", { network: Network.Testnet }); - - expect(tree.toHex()).to.be.equal("18090104c801d191a37300"); - expect(tree.hasSegregatedConstants).to.be.equal(true); - expect(tree.hasSize).to.be.equal(true); + it("Should throw if version is greater than max supported", () => { + expect(() => + compile("sigmaProp(HEIGHT > 100)", { + version: 10 + } as unknown as CompilerOptions) + ).to.throw("Version should be lower than 8, got 10"); }); }); diff --git a/packages/compiler/src/compiler.ts b/packages/compiler/src/compiler.ts index 160c9a76..6f4b23bc 100644 --- a/packages/compiler/src/compiler.ts +++ b/packages/compiler/src/compiler.ts @@ -1,4 +1,4 @@ -import { assert, ergoTreeHeaderFlags, isEmpty, isHex, Network } from "@fleet-sdk/common"; +import { assert, ergoTreeHeaderFlags, isEmpty, isHex } from "@fleet-sdk/common"; import { ISigmaType, SConstant } from "@fleet-sdk/core"; import { SigmaCompilerNamedConstantsMap, @@ -8,29 +8,46 @@ import { } from "sigmastate-js/main"; import { CompilerOutput } from "./compilerOutput"; -export type CompilerOptions = { +type CompilerOptionsBase = { + version?: number; map?: NamedConstantsMap; segregateConstants?: boolean; +}; + +export type CompilerOptionsForErgoTreeV0 = CompilerOptionsBase & { + version?: 0; includeSize?: boolean; - network?: Network; }; +export type CompilerOptionsForErgoTreeV1 = CompilerOptionsBase & { + version?: 1; +}; + +export type CompilerOptions = CompilerOptionsForErgoTreeV0 | CompilerOptionsForErgoTreeV1; + export type NamedConstantsMap = { [key: string]: string | ISigmaType | SigmaValue; }; -export function compile(script: string, options: CompilerOptions = {}): CompilerOutput { - const { - map = options.map ?? {}, - segregateConstants = options.segregateConstants ?? true, - network = options.network ?? Network.Mainnet, - includeSize = options.includeSize ?? true - } = options; - - const headerFlags = includeSize ? ergoTreeHeaderFlags.sizeInclusion : 0x00; - const tree = constructCompiler(network).compile( - parseNamedConstantsMap(map), - segregateConstants, +export const compilerDefaults: Required = { + version: 1, + map: {}, + segregateConstants: true +}; + +export function compile(script: string, options?: CompilerOptions): CompilerOutput { + const opt = ensureDefaults(options, compilerDefaults); + assert(opt.version < 8, `Version should be lower than 8, got ${opt.version}`); + + let headerFlags = 0x00 | opt.version; + + if (opt.version > 0 || (opt.version == 0 && opt.includeSize)) { + headerFlags |= ergoTreeHeaderFlags.sizeInclusion; + } + + const tree = SigmaCompilerObj.forMainnet().compile( + parseNamedConstantsMap(opt.map), + opt.segregateConstants, headerFlags, script ); @@ -38,10 +55,18 @@ export function compile(script: string, options: CompilerOptions = {}): Compiler return new CompilerOutput(tree); } -function constructCompiler(network: Network) { - return network === Network.Mainnet - ? SigmaCompilerObj.forMainnet() - : SigmaCompilerObj.forTestnet(); +function ensureDefaults( + options: T | undefined, + defaults: Required +): Required { + if (isEmpty(options)) return defaults; + + const newObj: Required = { ...defaults, ...options }; + for (const key in newObj) { + newObj[key] = options[key] ?? defaults[key]; + } + + return newObj; } export function parseNamedConstantsMap(map: NamedConstantsMap): SigmaCompilerNamedConstantsMap {