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

Support full image specification of dockerized integrated-devnet #406

Merged
merged 7 commits into from
Sep 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
38 changes: 32 additions & 6 deletions src/external-server/create-devnet-wrapper.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,39 @@
import { HardhatNetworkConfig, HardhatRuntimeEnvironment } from "hardhat/types";
import { StarknetPluginError } from "../starknet-plugin-error";

import { DEVNET_DOCKER_REPOSITORY, INTEGRATED_DEVNET, INTEGRATED_DEVNET_URL } from "../constants";
import {
DEFAULT_DEVNET_DOCKER_IMAGE_TAG,
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";
import { Image } from "@nomiclabs/hardhat-docker";

function getDevnetImage(dockerizedVersion: string = DEFAULT_DEVNET_DOCKER_IMAGE_TAG): Image {
let repository: string = undefined;
let tag: string = undefined;

// check if of format <image>:<tag>
if (dockerizedVersion.includes(":")) {
const imageParts = dockerizedVersion.split(":");
if (imageParts.length !== 2) {
const msg = `Invalid dockerizedVersion: "${dockerizedVersion}". Expected <tag> or <image>:<tag>`;
throw new StarknetPluginError(msg);
}
repository = imageParts[0];
tag = imageParts[1];
} else {
// treat as a devnet-py tag
repository = DEVNET_DOCKER_REPOSITORY;
tag = getDevnetImageTagByArch(dockerizedVersion);
}

return { repository, tag };
}

export function createIntegratedDevnet(hre: HardhatRuntimeEnvironment): ExternalServer {
const devnetNetwork = getNetwork<HardhatNetworkConfig>(
Expand Down Expand Up @@ -37,12 +65,10 @@ export function createIntegratedDevnet(hre: HardhatRuntimeEnvironment): External
);
}

const tag = getDevnetImageTagByArch(devnetNetwork.dockerizedVersion);
const image = getDevnetImage(devnetNetwork.dockerizedVersion);

return new DockerDevnet(
{
repository: DEVNET_DOCKER_REPOSITORY,
tag
},
image,
hostname,
port,
devnetNetwork?.args,
Expand Down
7 changes: 3 additions & 4 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ import {
INTEGRATED_DEVNET_INTERNALLY,
StarknetChainId,
UDC_ADDRESS,
CAIRO_CLI_DEFAULT_DOCKER_IMAGE_TAG,
DEFAULT_DEVNET_DOCKER_IMAGE_TAG
CAIRO_CLI_DEFAULT_DOCKER_IMAGE_TAG
} from "./constants";
import { getContractFactoryUtil } from "./extend-utils";
import { StarknetPluginError } from "./starknet-plugin-error";
Expand Down Expand Up @@ -237,7 +236,7 @@ export function copyWithBigint<T>(object: unknown): T {
function getImageTagByArch(tag: string): string {
// Check CPU architecture
const arch = process.arch;
if (arch === "arm64" && !tag.endsWith("-arm")) {
if (arch === "arm64" && !tag.endsWith("-arm") && !tag.endsWith("-arm-seed0")) {
tag = `${tag}-arm`;
}
return tag;
Expand All @@ -247,7 +246,7 @@ export function getCairoCliImageTagByArch(tag = CAIRO_CLI_DEFAULT_DOCKER_IMAGE_T
return getImageTagByArch(tag);
}

export function getDevnetImageTagByArch(tag = DEFAULT_DEVNET_DOCKER_IMAGE_TAG): string {
export function getDevnetImageTagByArch(tag: string): string {
return getImageTagByArch(tag);
}

Expand Down
25 changes: 25 additions & 0 deletions test/integrated-devnet-tests/with-docker-full-image/check.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { hardhatStarknetTest } from "../../utils/cli-functions";
import { checkDevnetIsNotRunning } from "../../utils/utils";

// Test how full image specification is handled

(async () => {
// no danger in using a devnet to whose API we are not adapted (latest)
// as this test only relies on /is_alive
for (const devnetVersion of [
"shardlabs/starknet-devnet:latest",
"shardlabs/starknet-devnet-rs:latest"
]) {
await checkDevnetIsNotRunning();
process.env.STARKNET_DEVNET = devnetVersion;
hardhatStarknetTest([
"--no-compile",
"test/integrated-devnet.test.ts",
// run just the one test from the file
"--grep",
"\"should have devnet endpoint alive\""
]);
}

await checkDevnetIsNotRunning();
})();
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import "@shardlabs/starknet-hardhat-plugin";

module.exports = {
starknet: {
network: process.env.NETWORK
},
networks: {
integratedDevnet: {
dockerizedVersion: process.env.STARKNET_DEVNET,
url: "http://127.0.0.1:5050"
}
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"$schema": "../../network.schema",
"integrated-devnet": true
}
20 changes: 17 additions & 3 deletions www/docs/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -630,11 +630,22 @@ Predefined networks include `alpha-goerli`, `alpha-goerli2`, `alpha-mainnet` and

By defining/modifying `networks["integratedDevnet"]` in your hardhat config file, you can specify:

- the version of Devnet to use (effectively specifying the version of the underlying Docker image)
- the version of dockerized Devnet to use
- a Python environment with installed starknet-devnet (can be active environment); this will avoid using the dockerized version
- CLI arguments to be used on Devnet startup: [options](https://0xspaceshard.github.io/starknet-devnet/docs/guide/run)
- where output should be flushed _(either to the terminal or to a file)_.

#### Dockerized Integrated Devnet

Dockerized integrated-devnet is the default mode, but can be specified via the `dockerizedVersion` property of `integratedDevnet`:

- the full image can be provided:
- `shardlabs/starknet-devnet:<TAG>` (Pythonic Devnet) - [Docker image info](https://0xspaceshard.github.io/starknet-devnet/docs/guide/run/#run-with-docker)
- `shardlabs/starknet-devnet-rs:<TAG>` (Rust Devnet) - [Docker image info](https://github.com/0xSpaceShard/starknet-devnet-rs#run-with-docker)
- if just `<TAG>` is provided, it defaults to Pythonic Devnet

#### Integrated Devnet config example

```javascript
module.exports = {
starknet: {
Expand All @@ -648,16 +659,19 @@ module.exports = {
// venv: "path/to/venv" <- for env with installed starknet-devnet (created with e.g. `python -m venv path/to/venv`)
venv: "<VENV_PATH>",

// use python or rust vm implementation
// This section covers the VM selection in Pythonic Devnet (starknet-devnet): Python VM or Rust VM
// This is distinct from selecting between Pythonic Devnet and Rust Devnet, which can be done via `dockerizedVersion`
// vmLang: "python" <- use python vm (default value)
// vmLang: "rust" <- use rust vm
// (rust vm is available out of the box using dockerized integrated-devnet)
// (rustc and cairo-rs-py required using installed devnet)
// read more here : https://0xspaceshard.github.io/starknet-devnet/docs/guide/run/#run-with-the-rust-implementation-of-cairo-vm
vmLang: "<VM_LANG>",

// or specify Docker image tag
// or use dockerized Devnet by specifying [IMAGE:]<TAG> (if IMAGE omitted - defaults to "shardlabs/starknet-devnet")
dockerizedVersion: "<DEVNET_VERSION>",
// dockerizedVersion: "shardlabs/starknet-devnet:<TAG>",
// dockerizedVersion: "shardlabs/starknet-devnet-rs:<TAG>",

// optional devnet CLI arguments, read more here: https://0xspaceshard.github.io/starknet-devnet/docs/guide/run
args: ["--gas-price", "2000000000", "--fork-network", "alpha-goerli"],
Expand Down