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 cairo-lang/Starknet 0.11.2; support scarb #376

Merged
merged 51 commits into from
Jun 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
1570912
Update tools
FabijanC Jun 1, 2023
71febe1
Install toml parser
FabijanC Jun 12, 2023
8e10f1c
Add initial scarb support - venv only [skip ci]
FabijanC Jun 12, 2023
2dddbad
Remove symlink approach leftover [skip ci]
FabijanC Jun 13, 2023
f349de8
Refactor to use scarb class wrappers (docker WIP) [skip ci]
FabijanC Jun 14, 2023
9abe5e1
Fix custom scarb + handle no projects [skip ci]
FabijanC Jun 15, 2023
5665125
Add dockerized scarb support [WIP - mounting][skip ci]
FabijanC Jun 15, 2023
d41d03d
Fix dockerized scarb support [skip ci]
FabijanC Jun 16, 2023
72b5c8e
Add scarb toml validation [skip ci]
FabijanC Jun 19, 2023
1f18c9d
Rename validation error, improve msg [skip ci]
FabijanC Jun 19, 2023
700c8e0
Improve code comments [skip ci]
FabijanC Jun 19, 2023
5c470c3
Move TODOs to issue #384 [skip ci]
FabijanC Jun 19, 2023
a4bf0c9
Add scarb installation step [skip ci]
FabijanC Jun 19, 2023
73769be
Use @iarna/toml instead of toml
FabijanC Jun 20, 2023
0e22d05
Add with-scarb-dockerized [skip ci] [WIP]
FabijanC Jun 20, 2023
1018a49
Support array in complex output [skip ci]
FabijanC Jun 21, 2023
7eaa8f9
Add tests [skip ci]
FabijanC Jun 21, 2023
70ca814
Remove refactoring TODO
FabijanC Jun 21, 2023
13db1df
Fix minor shell script errors
FabijanC Jun 22, 2023
5de3113
Change example repo branch
FabijanC Jun 22, 2023
aa9bd5e
Remove python3.8 from caching
FabijanC Jun 22, 2023
f058e72
Fix scarb installation
FabijanC Jun 22, 2023
8dcc42e
Fix getting of docker image
FabijanC Jun 22, 2023
1b2d67e
Fix hardhat config; add validation
FabijanC Jun 22, 2023
85988be
Use /tmp for scarb cache dir
FabijanC Jun 22, 2023
6977576
Add venv test
FabijanC Jun 22, 2023
7219c1d
Rename scarb-path test to scarb-custom-command
FabijanC Jun 22, 2023
bea4036
Move hardhat config validation after cp
FabijanC Jun 22, 2023
8380037
Check scarb installation
FabijanC Jun 22, 2023
09e9f12
Prevent invalid config from exiting test.sh
FabijanC Jun 22, 2023
e9e1edc
Fix scarb installation
FabijanC Jun 22, 2023
4bde2ef
Prevent solidity recompilation in scarb tests
FabijanC Jun 22, 2023
5315675
Fix fetching devnet image
FabijanC Jun 22, 2023
f4fb456
Fix lint error
FabijanC Jun 22, 2023
9073172
chown /tmp on circleci
FabijanC Jun 22, 2023
edb1e2e
Remove venv-tests/with-scarb-custom-command
FabijanC Jun 22, 2023
bcd8363
Suspend configuration-tests/disallow-cairo1BinDir-when-dockerized
FabijanC Jun 22, 2023
607cf9c
Fix typo
FabijanC Jun 22, 2023
600ff71
Fix scarb init error logging
FabijanC Jun 22, 2023
392059c
Remove test/configuration-tests/disallow-cairo1BinDir-when-dockerized
FabijanC Jun 22, 2023
095ed7b
Fix with-scarb-custom-command-cli test
FabijanC Jun 22, 2023
c9bc3e3
Disable dockerized scarb
FabijanC Jun 22, 2023
fa08116
Fix dockerized scarb test
FabijanC Jun 22, 2023
5833936
Add docs [skip ci]
FabijanC Jun 22, 2023
a7a42cb
Fix scarb tests
FabijanC Jun 22, 2023
68255c5
Install starknet-devnet v0.5.4
FabijanC Jun 22, 2023
5d1a036
Minor fixes after review
FabijanC Jun 22, 2023
cb154cc
Improve docs
FabijanC Jun 22, 2023
eceff40
Remove hardhat config check
FabijanC Jun 22, 2023
6b23e53
Fix scarb invalid config test
FabijanC Jun 22, 2023
1732514
Restore example repo branch [skip ci]
FabijanC Jun 22, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ aliases:
name: "Save cairo-lang Cache"
key: cairo-lang-cache-{{ arch }}-v1-{{ checksum "/tmp/cairo-lang-version" }}
paths:
- /usr/python3.8/dist-packages/cairo-lang
- /usr/python3.9/dist-packages/cairo-lang
- /usr/local/bin/starknet
- /usr/local/bin/starknet-compile
Expand All @@ -133,7 +132,6 @@ aliases:
- /opt/circleci/.pyenv/versions
- /opt/circleci/.pyenv/shims/starknet-devnet
- /usr/local/bin/starknet-devnet
- /usr/local/lib/python3.8/site-packages
- /usr/local/lib/python3.9/site-packages

# Commands
Expand Down
7 changes: 4 additions & 3 deletions config.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"CAIRO_LANG": "0.11.1.1",
"STARKNET_DEVNET": "0.5.2",
"CAIRO_COMPILER": "v1.0.0-rc0"
"CAIRO_LANG": "0.11.2",
"STARKNET_DEVNET": "0.5.4",
"CAIRO_COMPILER": "v1.1.0",
"SCARB_VERSION": "0.4.0"
}
6 changes: 6 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"author": "SpaceShard",
"license": "MIT",
"dependencies": {
"@iarna/toml": "^2.2.5",
"@nomiclabs/hardhat-docker": "^2.0.2",
"axios": "^1.0.0",
"axios-retry": "^3.5.0",
Expand Down
10 changes: 10 additions & 0 deletions scripts/test-setup.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
#!/bin/bash

set -eu
set -o pipefail

trap 'for killable in $(jobs -p); do kill -9 $killable; done' EXIT

# log versions
./scripts/versions.sh

./scripts/ensure-python.sh

# setup example repo
Expand All @@ -27,3 +33,7 @@ fi

# used by some cases
../scripts/setup-venv.sh

# install scarb
SCARB_VERSION=$(jq -r ".SCARB_VERSION" ../config.json)
curl --proto '=https' --tlsv1.2 -sSf https://docs.swmansion.com/scarb/install.sh | bash -s -- -v "$SCARB_VERSION"
1 change: 1 addition & 0 deletions scripts/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ function run_test() {

# replace the dummy config (CONFIG_FILE_NAME) with the one used by this test
/bin/cp "$config_file_path" "$CONFIG_FILE_NAME"
# in the future - validate config file here

# check if test_case/check.ts exists
if [ -f "$test_case/check.ts" ]; then
Expand Down
4 changes: 2 additions & 2 deletions scripts/versions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ echo "node: $(node --version)"
echo "npm: $(npm --version)"

#these two commands may return different versions (e.g. if using circleci/node and remote docker)
echo "docker: $(docker --version)"
docker version
echo "docker --version: $(docker --version)"
echo "docker version: $(docker version)"

echo "python3: $(python3 --version)"
echo "pip3: $(pip3 --version)"
58 changes: 34 additions & 24 deletions src/adapt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,33 @@ function adaptStructInput(
}
}

/**
* resultIndex initially expected to be at value indicating array length
*/
function adaptArray(result: bigint[], resultIndex: number, arrayType: string, abi: starknet.Abi) {
const elementType = arrayType.slice(
ARRAY_TYPE_PREFIX.length,
arrayType.length - ARRAY_TYPE_SUFFIX.length
);

const adaptedArray = [];

// Iterate over the result array, starting with current `resultIndex`
const expectedLength = Number(result[resultIndex++]);
for (let i = 0; i < expectedLength; i++) {
// Generate a struct with each element of the array and push it to `adaptedArray`
const ret = generateComplexOutput(result, resultIndex, elementType, abi);
adaptedArray.push(ret.generatedComplex);
// Next index is the proper raw index returned from generating the struct, which accounts for nested structs
resultIndex = ret.newRawIndex;
}

return {
adaptedArray,
newResultIndex: resultIndex
};
}

/**
* Adapts the string resulting from a Starknet CLI function call or server purpose of adapting event
* This is done according to the actual output type specified by the called function.
Expand Down Expand Up @@ -487,30 +514,9 @@ export function adaptOutputUtil(
// New resultIndex is the raw index generated from the last struct
adapted[outputSpec.name] = structArray;
} else if (isArray(outputSpec.type)) {
const outputSpecArrayElementType = outputSpec.type.slice(
ARRAY_TYPE_PREFIX.length,
outputSpec.type.length - ARRAY_TYPE_SUFFIX.length
);
const arrLength = Number(currentValue);
resultIndex++;

const structArray = [];

// Iterate over the struct array, starting with results at `resultIndex`
for (let i = 0; i < arrLength; i++) {
// Generate a struct with each element of the array and push it to `structArray`
const ret = generateComplexOutput(
result,
resultIndex,
outputSpecArrayElementType,
abi
);
structArray.push(ret.generatedComplex);
// Next index is the proper raw index returned from generating the struct, which accounts for nested structs
resultIndex = ret.newRawIndex;
}
// New resultIndex is the raw index generated from the last struct
adapted[outputSpec.name] = structArray;
const ret = adaptArray(result, resultIndex, outputSpec.type, abi);
resultIndex = ret.newResultIndex;
adapted[outputSpec.name] = ret.adaptedArray;
} else {
const ret = generateComplexOutput(result, resultIndex, outputSpec.type, abi);
adapted[outputSpec.name] = ret.generatedComplex;
Expand Down Expand Up @@ -578,6 +584,10 @@ function generateComplexOutput(raw: bigint[], rawIndex: number, type: string, ab
rawIndex = ret.newRawIndex;
}
}
} else if (isArray(type)) {
const ret = adaptArray(raw, rawIndex, type, abi);
generatedComplex = ret.adaptedArray;
rawIndex = ret.newResultIndex;
} else {
// struct
if (!(type in abi)) {
Expand Down
1 change: 1 addition & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export const CAIRO1_SIERRA_SUFFIX = ".json";
export const CAIRO1_COMPILE_BIN = "starknet-compile";
export const CAIRO1_SIERRA_COMPILE_BIN = "starknet-sierra-compile";
export const DOCKER_HOST_BIN_PATH = "/usr/local/bin/target/release";
export const SUPPORTED_SCARB_VERSION = config["SCARB_VERSION"];

export const DEFAULT_STARKNET_SOURCES_PATH = "contracts";
export const DEFAULT_STARKNET_ARTIFACTS_PATH = "starknet-artifacts";
Expand Down
13 changes: 3 additions & 10 deletions src/external-server/create-devnet-wrapper.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
import { HardhatNetworkConfig, HardhatRuntimeEnvironment } from "hardhat/types";
import { StarknetPluginError } from "../starknet-plugin-error";

import {
DEFAULT_DEVNET_DOCKER_IMAGE_TAG,
DEVNET_DOCKER_REPOSITORY,
INTEGRATED_DEVNET,
INTEGRATED_DEVNET_URL
} from "../constants";
import { getImageTagByArch, getNetwork } from "../utils";
import { DEVNET_DOCKER_REPOSITORY, INTEGRATED_DEVNET, INTEGRATED_DEVNET_URL } from "../constants";
import { getDevnetImageTagByArch, getNetwork } from "../utils";
import { DockerDevnet } from "./docker-devnet";
import { VenvDevnet } from "./venv-devnet";
import { ExternalServer } from "./external-server";
Expand Down Expand Up @@ -42,9 +37,7 @@ export function createIntegratedDevnet(hre: HardhatRuntimeEnvironment): External
);
}

const tag = getImageTagByArch(
devnetNetwork.dockerizedVersion || DEFAULT_DEVNET_DOCKER_IMAGE_TAG
);
const tag = getDevnetImageTagByArch(devnetNetwork.dockerizedVersion);
return new DockerDevnet(
{
repository: DEVNET_DOCKER_REPOSITORY,
Expand Down
47 changes: 37 additions & 10 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import "./type-extensions";
import {
DEFAULT_STARKNET_SOURCES_PATH,
DEFAULT_STARKNET_ARTIFACTS_PATH,
CAIRO_CLI_DEFAULT_DOCKER_IMAGE_TAG,
CAIRO_CLI_DOCKER_REPOSITORY,
AMARNA_DOCKER_REPOSITORY,
AMARNA_DOCKER_IMAGE_TAG,
Expand All @@ -30,14 +29,15 @@ import {
VOYAGER_MAINNET_VERIFIED_URL,
VOYAGER_GOERLI_2_CONTRACT_API_URL,
VOYAGER_GOERLI_2_VERIFIED_URL,
StarknetChainId
StarknetChainId,
SUPPORTED_SCARB_VERSION
} from "./constants";
import {
adaptPath,
getAccountPath,
getCairoCliImageTagByArch,
getDefaultHardhatNetworkConfig,
getDefaultHttpNetworkConfig,
getImageTagByArch,
getNetwork
} from "./utils";
import { DockerWrapper, VenvWrapper } from "./starknet-wrappers";
Expand All @@ -51,7 +51,8 @@ import {
starknetMigrateAction,
starknetNewAccountAction,
starknetDeployAccountAction,
starknetCompileCairo1Action
starknetCompileCairo1Action,
starknetBuildAction
} from "./task-actions";
import {
bigIntToShortStringUtil,
Expand Down Expand Up @@ -195,9 +196,7 @@ extendEnvironment((hre) => {
setVenvWrapper(hre, venvPath);
} else {
const repository = CAIRO_CLI_DOCKER_REPOSITORY;
const tag = getImageTagByArch(
hre.config.starknet.dockerizedVersion || CAIRO_CLI_DEFAULT_DOCKER_IMAGE_TAG
);
const tag = getCairoCliImageTagByArch(hre.config.starknet.dockerizedVersion);

const image = { repository, tag };
const accountPaths = extractAccountPaths(hre);
Expand Down Expand Up @@ -235,7 +234,7 @@ task("starknet-compile-deprecated", "Compiles Starknet (Cairo 0) contracts")
.addOptionalVariadicPositionalParam(
"paths",
"The paths to be used for compilation.\n" +
"Each of the provided paths is recursively looked into while searching for compilation artifacts.\n" +
"Each of the provided paths is recursively looked into while searching for source files.\n" +
"If no paths are provided, the default contracts directory is traversed."
)
.addOptionalParam(
Expand All @@ -251,8 +250,9 @@ task("starknet-compile", "Compiles Starknet (Cairo 1) contracts")
.addOptionalVariadicPositionalParam(
"paths",
"The paths are source files of contracts to be compiled.\n" +
"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."
"Each of the provided paths is recursively looked into while searching for source files.\n" +
"If no paths are provided, the default contracts directory is traversed.\n" +
"To build more complex Cairo 1 projects, read about `hardhat starknet-build`"
)
.addOptionalParam(
"cairo1BinDir",
Expand All @@ -268,6 +268,33 @@ task("starknet-compile", "Compiles Starknet (Cairo 1) contracts")
.addFlag("addPythonicHints", "Add pythonic hints.")
.setAction(starknetCompileCairo1Action);

task("starknet-build", "Builds Scarb projects")
.addOptionalVariadicPositionalParam(
"paths",
"The paths are source files of contracts to be compiled.\n" +
"Each of the provided paths is recursively looked into while searching for Scarb projects.\n" +
"If no paths are provided, the default contracts directory is traversed.\n" +
`Each project must be a valid Scarb ${SUPPORTED_SCARB_VERSION} project with lib.cairo and Scarb.toml in its root.\n` +
"The toml file must have `sierra` and `casm` set to `true` under [[target.starknet-contract]].\n" +
"In code, load the generated contracts with an underscore-separated string:\n" +
"\tstarknet.getContractFactory('<PACKAGE_NAME>_<CONTRACT_NAME>')\n" +
"E.g. if your toml specifies `name = MyPackage` and there is a contract called FooContract in your source files, you would load it with:\n" +
"\tstarknet.getContractFactory('MyPackage_FooContract')\n" +
"The name of the file where the contract was defined doesn't play a role.\n" +
"If you do not provide a `scarbCommand` (either an exact command or the path to it) under `starknet` in your hardhat config file, " +
"you may specify (and even override) it via `--scarb-command <COMMAND>`."
)
.addOptionalParam(
"scarbCommand",
"Your local Scarb command or path to the executable file. Overrides the one set in the hardhat config file"
)
.addFlag(
"skipValidate",
"By default, your TOML config file will be validated to ensure it generates the artifacts required for later contract loading.\n" +
"Set this flag to skip the validation."
)
.setAction(starknetBuildAction);

extendEnvironment((hre) => {
hre.starknet = {
getContractFactory: async (contractPath) => {
Expand Down
Loading