Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adapt to starknet 0.11.0 #328

Merged
merged 62 commits into from
Apr 17, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
47b3e38
Update to cairo-lang 0.11.0a0 [skip ci]
Nathan-SL Mar 2, 2023
bf858aa
Support cairo1 compilation with manifest path [skip ci]
Nathan-SL Mar 15, 2023
41dbf34
WIP: Support for cairo1 compilation with docker [skip ci]
Nathan-SL Mar 15, 2023
80b8fe3
Merge branch 'master' into addapt-0.11.0
Nathan-SL Mar 15, 2023
c95c950
Set conditional volume to mount [skip ci]
Nathan-SL Mar 15, 2023
4f5c72d
Update python version
Nathan-SL Mar 27, 2023
f168d36
Change contract_address to sender_address
Nathan-SL Mar 27, 2023
9614128
Support declare v2 [skip ci]
Nathan-SL Mar 30, 2023
28904d9
Update to latest cairo-lang and starknet-devnet
Nathan-SL Mar 31, 2023
d15f9f7
Add declare v2 test
Nathan-SL Mar 31, 2023
3c8a467
Remove cargo_run func from starknet_cli_wrapper
Nathan-SL Apr 4, 2023
d6455a6
Update cairo1-compiler with docker
Nathan-SL Apr 4, 2023
a489ca1
Update cli funcs in test
Nathan-SL Apr 4, 2023
2830638
Adapt inputs and outputs based on new data types
Nathan-SL Apr 4, 2023
5a95efc
Support dokerized compilation for cairo1
Nathan-SL Apr 4, 2023
270add3
Update docs [skip ci]
Nathan-SL Apr 4, 2023
e5836b3
Recompiler support cairo1 constracts
Nathan-SL Apr 4, 2023
ddef382
Silent vmlang-rust test
Nathan-SL Apr 4, 2023
31b7e86
Adapt with starknet-devnet
Nathan-SL Apr 4, 2023
93d9bd2
Skip old cairo contracts on cairo1 compilation
Nathan-SL Apr 6, 2023
4b771e7
Add docs [skip ci]
Nathan-SL Apr 6, 2023
cc9c7f7
Remove arg [skip ci]
Nathan-SL Apr 6, 2023
5ec0369
Avoid cairo contract checking
Nathan-SL Apr 6, 2023
f138758
Update python version
Nathan-SL Apr 6, 2023
46aef66
Rename declare v2 constant
Nathan-SL Apr 7, 2023
63c0fbb
Add more common types
Nathan-SL Apr 7, 2023
d71f442
Add jsdoc for function formatSpaces
Nathan-SL Apr 7, 2023
50863de
Use separate interface for cairo1 compiler options
Nathan-SL Apr 7, 2023
da1e614
Set declarev2 private
Nathan-SL Apr 7, 2023
97ff6b3
Update cli docs
Nathan-SL Apr 11, 2023
f8e9fd4
Change type ContractClass to ts class
Nathan-SL Apr 11, 2023
cb381b8
Add function to check a constructor
Nathan-SL Apr 11, 2023
bdbfc95
Require maxFee for declareV2
Nathan-SL Apr 11, 2023
ac1a879
Add extra test
Nathan-SL Apr 12, 2023
886446a
Add cairo1-compiler to CI/CD
Nathan-SL Apr 12, 2023
bb6621f
Set file executable
Nathan-SL Apr 12, 2023
1f0cc05
Update script
Nathan-SL Apr 12, 2023
ff7d0d6
Update script
Nathan-SL Apr 12, 2023
f651a72
Update script
Nathan-SL Apr 12, 2023
719d609
Remove unused variable [skip ci]
Nathan-SL Apr 12, 2023
3b315c7
Update script
Nathan-SL Apr 12, 2023
47d7821
Update manifestPath
Nathan-SL Apr 12, 2023
d9e027c
Update script
Nathan-SL Apr 13, 2023
96eff06
Setup cairo1-compiler from package.json
Nathan-SL Apr 13, 2023
8637744
Remove source from scripts
Nathan-SL Apr 13, 2023
6ee1082
Update script
Nathan-SL Apr 14, 2023
eba36cb
Fix path
Nathan-SL Apr 14, 2023
dc78ddf
Add check for test subdir [skip ci]
Nathan-SL Apr 14, 2023
504c950
Add more type [skip ci]
Nathan-SL Apr 14, 2023
9ba7e4e
Avoid unnecessary venvPath checking
Nathan-SL Apr 17, 2023
556fa3b
Rename funcs
Nathan-SL Apr 17, 2023
299bf57
Remove unnecessary class property
Nathan-SL Apr 17, 2023
4e34b4a
Avoid if block
Nathan-SL Apr 17, 2023
83def43
Avoid duplicate logs
Nathan-SL Apr 17, 2023
12a7704
Remove optional param from start func
Nathan-SL Apr 17, 2023
9fa8a45
Enhance error message
Nathan-SL Apr 17, 2023
920f33e
Change class name
Nathan-SL Apr 17, 2023
84528c0
Update docs [skip ci]
Nathan-SL Apr 17, 2023
3dc9d4d
Remove bool from common types
Nathan-SL Apr 17, 2023
dd9a11f
Avoid use of docker server on DockerCairo1Compiler
Nathan-SL Apr 17, 2023
35247d5
Restore branch [skip ci]
Nathan-SL Apr 17, 2023
d118675
Update docs [skip ci]
Nathan-SL Apr 17, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion config.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"CAIRO_LANG": "0.10.3",
"CAIRO_LANG": "0.11.0a0",
"STARKNET_DEVNET": "0.4.6"
}
2 changes: 2 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import config from "../config.json";

export const PLUGIN_NAME = "Starknet";
export const ABI_SUFFIX = "_abi.json";
export const SIERRA_SUFFIX = ".casm";
FabijanC marked this conversation as resolved.
Show resolved Hide resolved
export const CARGO_FILE = "Cargo.toml";
export const DEFAULT_STARKNET_SOURCES_PATH = "contracts";
export const DEFAULT_STARKNET_ARTIFACTS_PATH = "starknet-artifacts";
export const DEFAULT_STARKNET_ACCOUNT_PATH = "~/.starknet_accounts";
Expand Down
22 changes: 21 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ import {
starknetPluginVersionAction,
starknetMigrateAction,
starknetNewAccountAction,
starknetDeployAccountAction
starknetDeployAccountAction,
starknetCompileCairo1Action
} from "./task-actions";
import {
bigIntToShortStringUtil,
Expand Down Expand Up @@ -239,6 +240,25 @@ task("starknet-compile", "Compiles Starknet contracts")
.addFlag("disableHintValidation", "Allows compiling a contract with any python code in hints.")
.setAction(starknetCompileAction);

task("starknet-compile-cairo1", "Compiles Starknet cairo1 contracts")
.addOptionalVariadicPositionalParam(
"paths",
"The paths to be used for deployment.\n" +
FabijanC marked this conversation as resolved.
Show resolved Hide resolved
"Each of the provided paths is recursively looked into while searching for compilation artifacts.\n" +
"If no paths are provided, the default contracts directory is traversed."
)
.addOptionalParam(
"manifestPath",
"Allows to specify locally installed cairo1 compiler path.\n" +
"e.g. --manifest-path 'path/to/Cargo.toml' or can also be set on hardhat.config.ts file."
)
.addOptionalParam(
FabijanC marked this conversation as resolved.
Show resolved Hide resolved
"cairoPath",
"Allows specifying the locations of imported files, if necessary.\n" +
"Separate them with a colon (:), e.g. --cairo-path='path/to/lib1:path/to/lib2'"
)
.setAction(starknetCompileCairo1Action);

extendEnvironment((hre) => {
hre.starknet = {
getContractFactory: async (contractPath) => {
Expand Down
4 changes: 3 additions & 1 deletion src/starknet-docker-proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ export class StarknetDockerProxy extends DockerServer {
image: Image,
private rootPath: string,
private accountPaths: string[],
private cairoPaths: string[]
private cairoPaths: string[],
private manifestPath?: string
) {
super(image, "127.0.0.1", null, "", "starknet-docker-proxy");
}
Expand All @@ -35,6 +36,7 @@ export class StarknetDockerProxy extends DockerServer {
for (const mirroredPath of [this.rootPath, ...this.accountPaths, ...this.cairoPaths]) {
volumes.push("-v", `${mirroredPath}:${mirroredPath}`);
}
if (this.manifestPath) volumes.push("-v", `${this.manifestPath}:${this.manifestPath}`);

const dockerArgs = [...volumes];

Expand Down
51 changes: 48 additions & 3 deletions src/starknet-wrappers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@ import { FeeEstimation } from "./starknet-types";
import { hash } from "starknet";
import { toBN, toHex } from "starknet/utils/number";
import axios from "axios";
import path from "path";

interface CompileWrapperOptions {
file: string;
output: string;
abi: string;
abi?: string;
FabijanC marked this conversation as resolved.
Show resolved Hide resolved
cairoPath: string;
sierraOutput?: string;
manifestPath?: string;
accountContract: boolean;
disableHintValidation: boolean;
}
Expand Down Expand Up @@ -116,7 +119,7 @@ export abstract class StarknetWrapper {
}

public async execute(
command: "starknet" | "starknet-compile" | "get_class_hash" | "cairo-migrate",
command: "starknet" | "starknet-compile" | "get_class_hash" | "cairo-migrate" | "cargo",
args: string[]
): Promise<ProcessResult> {
return await this.externalServer.post<ProcessResult>({
Expand Down Expand Up @@ -153,6 +156,41 @@ export abstract class StarknetWrapper {
return executed;
}

private getCargoRunCommand(bin: string, manifestPath: string, args: string[]): string[] {
return [
"cargo",
"run",
"--bin",
bin,
"--manifest-path",
manifestPath,
"--",
args.join(" "),
"--allowed-libfuncs-list-name",
"experimental_v0.1.0"
];
}

protected preparedCairoOneCompileOptions(options: CompileWrapperOptions): string[] {
const cairoCompile = this.getCargoRunCommand("starknet-compile", options.manifestPath, [
options.file,
options.output
]);
const sierraCompile = this.getCargoRunCommand(
"starknet-sierra-compile",
options.manifestPath,
[options.output, options.sierraOutput]
);
const ret = [...cairoCompile, "&&", ...sierraCompile];
return ret;
}

public async cairo1Compile(options: CompileWrapperOptions): Promise<ProcessResult> {
const preparedOptions = this.preparedCairoOneCompileOptions(options);
const executed = await this.execute("cargo", preparedOptions);
return executed;
}

public prepareDeclareOptions(options: DeclareWrapperOptions): string[] {
const prepared = [
"declare",
Expand Down Expand Up @@ -465,7 +503,14 @@ export class DockerWrapper extends StarknetWrapper {
cairoPaths: string[],
hre: HardhatRuntimeEnvironment
) {
const externalServer = new StarknetDockerProxy(image, rootPath, accountPaths, cairoPaths);
const manifestPath = hre.config.starknet?.manifestPath;
const externalServer = new StarknetDockerProxy(
image,
rootPath,
accountPaths,
cairoPaths,
manifestPath ? manifestPath : path.dirname(manifestPath)
);
super(externalServer, hre);
console.log(
`${PLUGIN_NAME} plugin using dockerized environment (${getFullImageName(image)})`
Expand Down
23 changes: 19 additions & 4 deletions src/starknet_cli_wrapper.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Wrapper of Starknet CLI"""

import asyncio
import subprocess
from contextlib import redirect_stderr, redirect_stdout
from http.server import HTTPServer, BaseHTTPRequestHandler
import io
Expand All @@ -11,8 +12,8 @@
try:
from starkware.starknet.cli.starknet_cli import main as starknet_main
from starkware.starknet.compiler.compile import main as starknet_compile_main
from starkware.starknet.core.os.class_hash import compute_class_hash
from starkware.starknet.services.api.contract_class import ContractClass
from starkware.starknet.core.os.contract_class.deprecated_class_hash import compute_deprecated_class_hash
from starkware.starknet.services.api.contract_class.contract_class import DeprecatedCompiledClass
from starkware.cairo.lang.migrators.migrator import main as cairo_migrate_main
except ImportError:
sys.exit("Make sure the environment you configured has starknet (cairo-lang) installed!")
Expand All @@ -30,13 +31,26 @@ async def starknet_compile_main_wrapper(args):
print(err, file=sys.stderr)
return 1

async def cargo_run(args):
FabijanC marked this conversation as resolved.
Show resolved Hide resolved
sys.argv = [sys.argv[0], *args]
try:
args_split = " ".join(args).split("&&")
FabijanC marked this conversation as resolved.
Show resolved Hide resolved
starknet_compile = args_split[0]
starknet_sierra_compile = args_split[1]
subprocess.run(starknet_compile, shell=True)
subprocess.run(starknet_sierra_compile, shell=True)
return 0
except Exception as err:
print(err, file=sys.stderr)
return 1

async def get_class_hash(args):
path ,= args
with open(path, encoding="utf-8") as file:
raw_class = json.load(file)

loaded_class = ContractClass.load(raw_class)
class_hash = compute_class_hash(loaded_class)
loaded_class = DeprecatedCompiledClass.load(raw_class)
class_hash = compute_deprecated_class_hash(loaded_class)
print(hex(class_hash))
return 0

Expand All @@ -51,6 +65,7 @@ async def cairo_migrate_main_wrapper(args):
MAIN_MAP = {
"starknet": starknet_main_wrapper,
"starknet-compile": starknet_compile_main_wrapper,
"cargo": cargo_run,
"get_class_hash": get_class_hash,
"cairo-migrate": cairo_migrate_main_wrapper
}
Expand Down
91 changes: 90 additions & 1 deletion src/task-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ import * as fs from "fs";
import axios from "axios";
import FormData = require("form-data");
import { StarknetPluginError } from "./starknet-plugin-error";
import { ABI_SUFFIX, ALPHA_TESTNET, DEFAULT_STARKNET_NETWORK } from "./constants";
import {
ABI_SUFFIX,
ALPHA_TESTNET,
CARGO_FILE,
DEFAULT_STARKNET_NETWORK,
SIERRA_SUFFIX
} from "./constants";
import { ProcessResult } from "@nomiclabs/hardhat-docker";
import {
adaptLog,
Expand Down Expand Up @@ -74,6 +80,89 @@ function getFileName(filePath: string) {
return path.basename(filePath, path.extname(filePath));
}

export async function starknetCompileCairo1Action(
args: TaskArguments,
hre: HardhatRuntimeEnvironment
) {
const manifestPath = hre.config.starknet.manifestPath || args?.manifestPath;
if (!manifestPath) {
const msg =
"Could not find manifest-path\n" +
"The argument '—-manifest-path path/to/Cargo.toml' or manifestPath on hardhat.config.ts should be set.";
FabijanC marked this conversation as resolved.
Show resolved Hide resolved
FabijanC marked this conversation as resolved.
Show resolved Hide resolved
throw new StarknetPluginError(msg);
}

if (path.basename(manifestPath) !== CARGO_FILE) {
const msg = "The manifest-path must be a path to a Cargo.toml file";
throw new StarknetPluginError(msg);
}

const root = hre.config.paths.root;
const rootRegex = new RegExp("^" + root);

const defaultSourcesPath = hre.config.paths.starknetSources;
const sourcesPaths: string[] = args.paths || [defaultSourcesPath];
const artifactsPath = hre.config.paths.starknetArtifacts;

const cairoPaths = [defaultSourcesPath, root];
if (args.cairoPath) {
args.cairoPath.split(":").forEach((path: string) => {
cairoPaths.push(path);
});
}
if (hre.config.paths.cairoPaths) {
hre.config.paths.cairoPaths.forEach((path: string) => {
cairoPaths.push(path);
});
}
for (let i = 0; i < cairoPaths.length; i++) {
if (!path.isAbsolute(cairoPaths[i])) {
cairoPaths[i] = adaptPath(root, cairoPaths[i]);
}
}

const cairoPath = cairoPaths.join(":");
let statusCode = 0;
for (let sourcesPath of sourcesPaths) {
sourcesPath = adaptPath(root, sourcesPath);
checkSourceExists(sourcesPath);
const files = await traverseFiles(sourcesPath, "*.cairo");
const recompiler = new Recompiler(hre);
for (const file of files) {
console.log("Compiling", file);
const suffix = file.replace(rootRegex, "");
const fileName = getFileName(suffix);
const dirPath = path.join(artifactsPath, suffix);
const outputPath = path.join(dirPath, `${fileName}.json`);
const sierraOutput = path.join(dirPath, `${fileName}${SIERRA_SUFFIX}`);

fs.mkdirSync(dirPath, { recursive: true });
initializeFile(outputPath);
initializeFile(sierraOutput);

const executed = await hre.starknetWrapper.cairo1Compile({
file,
output: outputPath,
cairoPath,
sierraOutput,
manifestPath,
accountContract: args.accountContract,
FabijanC marked this conversation as resolved.
Show resolved Hide resolved
disableHintValidation: args.disableHintValidation
});

// Update cache after compilation
await recompiler.updateCache(args, file, outputPath, sierraOutput, cairoPath);
statusCode += processExecuted(executed, true);
}
await recompiler.saveCache();
}

if (statusCode) {
const msg = `Failed compilation of ${statusCode} contract${statusCode === 1 ? "" : "s"}.`;
throw new StarknetPluginError(msg);
}
}

export async function starknetCompileAction(args: TaskArguments, hre: HardhatRuntimeEnvironment) {
const root = hre.config.paths.root;
const rootRegex = new RegExp("^" + root);
Expand Down
1 change: 1 addition & 0 deletions src/types/starknet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ export type StarknetConfig = {
networkUrl?: string;
networkConfig?: NetworkConfig;
recompile?: boolean;
manifestPath?: string;
requestTimeout?: number;
};

Expand Down