Skip to content

Commit

Permalink
compiler: Set ErgoTree v1 as default output.
Browse files Browse the repository at this point in the history
  • Loading branch information
arobsn committed Jul 21, 2023
1 parent 8c6fa91 commit 4875f2a
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 47 deletions.
3 changes: 1 addition & 2 deletions .changeset/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,5 @@
"linked": [],
"access": "public",
"baseBranch": "master",
"updateInternalDependencies": "patch",
"ignore": ["@fleet-sdk/compiler"]
"updateInternalDependencies": "patch"
}
5 changes: 5 additions & 0 deletions .changeset/seven-zoos-own.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@fleet-sdk/compiler": minor
---

Set `ErgoTree` v1 as default output.
2 changes: 1 addition & 1 deletion packages/compiler/package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
87 changes: 62 additions & 25 deletions packages/compiler/src/compiler.spec.ts
Original file line number Diff line number Diff line change
@@ -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) } }
}
];

Expand All @@ -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;
Expand All @@ -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");
});
});

Expand Down
63 changes: 44 additions & 19 deletions packages/compiler/src/compiler.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -8,40 +8,65 @@ 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<CompilerOptions> = {
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
);

return new CompilerOutput(tree);
}

function constructCompiler(network: Network) {
return network === Network.Mainnet
? SigmaCompilerObj.forMainnet()
: SigmaCompilerObj.forTestnet();
function ensureDefaults<T extends object>(
options: T | undefined,
defaults: Required<T>
): Required<T> {
if (isEmpty(options)) return defaults;

const newObj: Required<T> = { ...defaults, ...options };
for (const key in newObj) {
newObj[key] = options[key] ?? defaults[key];
}

return newObj;
}

export function parseNamedConstantsMap(map: NamedConstantsMap): SigmaCompilerNamedConstantsMap {
Expand Down

0 comments on commit 4875f2a

Please sign in to comment.