Giter Club home page Giter Club logo

op-up's Introduction

op-up

CI Build Status Release Tag Build Status License Docs Latest Version rustc 1.70+

Composable OP Stack Orchestration System. alpha .

Install | User Docs | Crate Docs | Reference | Contributing | License

What is op-up?

op-up is the infrastructure for building composable OP Stack configurations. Given the growing number of OP Stack component implementations, having a simple service to spin up a composable devnet in a programmatical way is crucial for verifying superchain compatibility, general testing and experimentation.

The project was born out of the need to test out Magi, a rollup client built for the OP stack.

Have a new rollup derivation pipeline implementation for the OP Stack and want to test it?

Use op-up to configure an OP Stack with the new rollup derivation pipeline. Then, you can spin up a local devnet and run test suites against it!

What's the OP Stack?

The OP Stack is what powers the superchain!

It is a stack of various software components that, together, can be used to fully run a chain in the superchain. The Optimism Collective has already spent an enormous amount of effort and time building out the specifications for how OP Stack components work together in an interoperable way.

For example, want to run a pure rust op-stack?

You can use

  • reth as an L1 execution node.
  • op-reth as an L2 node (interchangeable with op-geth).
  • magi as the rollup node.

Notice, this does not include the proposer or batcher, as well as fault proof components.

Usage

Pre-requisites

First, install the following dependencies on your machine:

Installation

To get started with the interactive prompt, run the following commands:

git clone [email protected]:anton-rs/op-up.git && cd op-up
cargo run

This will bring up a local devnet using the default components.

Once the devnet is up and running, L1 is accessible at http://localhost:8545, and L2 is accessible at http://localhost:9545. Any Ethereum tool - Metamask, seth, etc. - can use these endpoints. Note that you will need to specify the L2 chain ID manually if you use Metamask. The devnet's L2 chain ID is 901.

The devnet comes with a pre-funded account you can use as a faucet:

  • Address: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266
  • Private key: ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80

The faucet account exists on both L1 and L2.


To stop the devnet, run:

cargo run -- stop

To reset the devnet state, run:

cargo run -- nuke

Using op-up as a library

By building with Rust's crate system, op-up can easily be used as a library in an extensible way.

Contributing

Please report any bugs or issues you encounter by opening a github issue.

All contributions are welcome, but if you are at all unsure, visit the developer docs.

License

This project is licensed under the MIT License. Free and open-source, forever.

All our rust are belong to you.

op-up's People

Stargazers

Alessandro Mazza avatar  avatar  avatar xinyao avatar Georges KABBOUCHI avatar Hashira avatar Marwan Hilmi avatar Stone Gao avatar Davirain avatar Lorenzo avatar Sabnock avatar SeungJu Lee avatar  avatar nicolas avatar Steph Sinyakov avatar Will Cory avatar zetsukhun avatar peak light avatar John Johnson avatar refcell avatar  avatar  avatar Etch avatar Michael Demarais avatar n0x avatar Paco avatar 0xYYY avatar ts0yu avatar Bakuchi avatar sudo rm -rf --no-preserve-root / avatar Anton Cheng avatar 0xhatsume avatar Sandalots avatar Georgios Konstantopoulos avatar  avatar  avatar sam avatar omar avatar Shun Kakinoki avatar Chen Kai avatar Noah Citron avatar

Watchers

Chen Kai avatar  avatar Kostas Georgiou avatar  avatar Shun Kakinoki avatar nicolas avatar

op-up's Issues

Documentation

Description

There are many areas of the codebase that need documentation, and two primary categories of docs to tackle.

Inline Documentation

This is a list of documentation issues for inline docs. These are doc comments that are inside source code files prefixed with a triple slash (///) that get compiled into documentation by rustdoc.

Markdown Docs

This is a list of issues for documenting items in markdown as part of the docs/ mdbook.

fix(stages): Cloning Abstractions

Description

Inside the stages crate, there is a stage/cannon.rs stage for the cannon prestate generation, a stage/allocs.rs Allocs stage for devnet allocs, and a cloning stage to clone the optimism monorepo.

This is a naive, sequential pipeline that starts with the cloning of the monorepo and then proceeds with generating the prestate and allocs.

This ticket is to make the monorepo cloning configurable through the stack.toml, such that under a [stages] table, a user can define something like isolate=true to force each stage to use isolate environments. In an optimism-monorepo exclusive stack, this would force each stage to clone the monorepo and execute it's behavior.

For non-isolated stages, the prestate stage would come first and check that the optimism monorepo is cloned, cloning it if not and leaving it available for all subsequent stages.

chore(docs): Primitives Documentation

Description

Minimal documentation should be done inline with extensive markdown book docs to avoid inconsistencies and duplication.

For this issue, the primitives crate readme.md file should be removed and minimal inline docs should be added to crates/primitives/src/lib.rs.

In the future, more extensive documentation will be added to documents in the docs/ mdbook.

chore(docs): Binary Documentation

Description

Following the precedent set in reth, minimal binary documentation should be done inline with extensive markdown book docs to avoid duplicate, and out-of-sync documentation.

For this issue, the opup binary readme.md file should be removed and minimal inline docs should be added to opup/src/lib.rs.

In the future, more extensive documentation will be added to documents in the docs/ mdbook.

feat(bin): Dry Run Flag

Description

The op-up binary should have a --dry-run flag to allow for "dry runs" for a given stack.

feat(stages): Support `Erigon` L1Client

In the L1 Executor stage, we should add support for the Erigon execution client.

match self.l1_client {
L1Client::Geth => self.start_geth().await?,
_ => unimplemented!("l1 client not implemented: {}", self.l1_client),
}

This will require setting up the Dockerfile (and an entrypoint file if necessry) and checking that:

  1. the image is built successfully
  2. the container is created successfully
  3. the container is started successfully
  4. the ports are bound correctly, and the assigned RPC API port is responding

CLI Subcommands

Description

Currently, the opup cli binary directly runs the op stack "devnet". It should be extended to accept Subcommands inside the Args struct, and then dispatch to the subcommand logic based on the selection. When no subcommand is provided, an inquire prompt should confirm that the user wants to run a stack based on the local stack.toml config file or environment variables + defaults if none is present. This prompt should not be shown when the up subcommand is passed into the cli.

For a subcommand reference implementation, see the reth binary.

Task List

chore: Remove Docker Artifacts

Description

Warning

Blocked by implementing component TOML configs in #14

Remove hardcoded docker artifacts - the docker directory - and replace with example op stack toml configuration files.

feat(composer): Docker network

We should add a Docker network for services to communicate with each other without the need to bind ports on the host.
Moreover, this will allow for communication via container names, e.g. ws://opup-l1:8586.

The Composer should create a network tagged with the same label as other opup components: com.docker.compose.project=op-up. By default each new container should be part of the same opup-net network but this should be configurable via the create_container function arguments.

chore(docs): Stages Documentation

Description

Minimal documentation should be done inline with extensive markdown book docs to avoid inconsistencies and duplication.

For this issue, the stages crate readme.md file should be removed and minimal inline docs should be added to crates/stages/src/lib.rs.

In the future, more extensive documentation will be added to documents in the docs/ mdbook.

bug: cargo run

cloned the op-up repo and when I run cargo run I get the error:
failed to run custom build command for jemalloc-sys v0.5.4+5.3.0-patched

chore(ci): MDBook Workflow

Description

Introduce a new book.yml github ci workflow based on reth's book.yaml.

This will require the specified https://stack.anton.systems url to point to a deployed github page.

Alternatively, there may be a way for a deployment service to automatically build and deploy the site on a trunk update. (ie when a pr is merged into main, some service automatically builds and deploys the mdbook to the specified https://stack.anton.systems site).

bug: allocs stage failure

When executing the up command, the allocs stage incurs in a critical failure.

error:

Exception: Exception occurred in child process: 
Command '['forge', 'script', 'scripts/Deploy.s.sol:Deploy', '--sender', 
'0x0dbf9c4872d17003bd9a9c3cd5b71bfff61cac4a', '--rpc-url', 'http://127.0.0.1:8545', 
'--broadcast', '--unlocked']' returned non-zero exit status 1

this error originates in the bedrock devnet python script here:

https://github.com/ethereum-optimism/optimism/blob/6bc21cb17702284a80e1a3e50fa70a996a721e97/bedrock-devnet/devnet/__init__.py#L129

fix(stages): Cannon Stage

Description

Inside the stages crate, there is a stage/cannon.rs stage for the cannon prestate generation.

The cannon stage should be renamed such that it is more closely tied to it's use as a fault proof system "hook" to generate the prestate instead of tying it down to "cannon".

The output of this issue should be to migration the cannon.rs module to something like prestate.rs.

feat(bin): Nuke Subcommand

Description

As part of #17, this task is to introduce a convenience nuke subcommand that nukes all running op-up stack components (including cleaning/pruning any docker containers, images, and volumes). Since this is a destructive command, it should use inquire to prompt the user to confirm that they want to perform the given actions (described in detail before the confirmation prompt).

Nuking logic should be entirely handled by the StageManager system orchestrator.

The extent of how to nuke stacks should be managed through cli flags and passed into the StageManager when executing the nuke() call. Since nuking also involves the local stack, the opup cli binary should build the StageManager from the config, and then call nuke() -> eyre::Result<()>. How the nuke cli flags are configured in the StageManager when building from the config or passing them directly in the nuke() call as arguments is an implementation detail, that is up to the implementor.

For example

StageManager::from(config).nuke()?;

Since the cli binary logic is minimal, it should be placed inside the cli.rs file where subcommand dispatching is handled.

chore(deps): check for missing dependencies

In the stages that don't use Docker (e.g. L1 genesis, L2 genesis, Prestate, Allocs) we should double check which dependencies are used. In particular, the make commands could hide dependencies by launching scripts with multiple steps inside.


  • Here we should add make to the list of binaries

/// Default binaries to check for.
pub const DEFAULT_BINARIES: &'static [&'static str] = &["docker", "curl", "tar"];

  • for go, we need to make a separate function go() similar to foundry() in the same file. The function should perform the brew install go command on MacOS, and use the package_manager() helper to install the package called golang-go on Linux. We can skip Windows at the moment.

fix(bin): Refactor List Subcommand

Description

The current opup list subcommand fetches a simple list of docker container information using the op-composer.

This subcommand should be migrated to a more generic opup inspect subcommand that inspects op stack info.
It should build a config from the stack.toml present in the executing directory or the global directory and use this config (along with its various component configs) to check if those components are running (docker or otherwise). This could probably be done by checking ports or alternatively, wrapping components with an op-up specific endpoint for querying the status of the component.

Other information like persistent volumes/data dirs could be queried using flags to inspect (e.g. opup inspect --volumes)

inspect could also provide a method of interacting directly with a component or changing its configuration on the fly. For example, opup inspect --mod <component_name>, which would open up a subshell with specific commands into that component. It might be easier to do this as a separate subcommand to the op-up binary though in another ticket like opup edge <component_name>.

feat(cli): CLI List Containers Subcommand

Description

Inside the op-composer crate, there is a list_containers method to list docker containers that have the op-up label.

A nice to have subcommand would be a simple cli subcommand like containers that would pretty print a nice list of op-up docker containers to stdout as a table

For example:

$ cargo run -- list

op-up docker containers
----------------------------------------------------------
| container            | status      | id       | size   |
----------------------------------------------------------
| l1-execution-client  | up: 1:24:00 | abcdefgh | 156gb  |
| l2-execution-client  | up: 1:24:00 | abcdefgi | 32gb   |
----------------------------------------------------------

chore(docs): Contracts Documentation

Description

Minimal documentation should be done inline with extensive markdown book docs to avoid inconsistencies and duplication.

For this issue, the contracts crate readme.md file should be removed and minimal inline docs should be added to crates/contracts/src/lib.rs.

In the future, more extensive documentation will be added to documents in the docs/ mdbook.

feat(bin): Down Subcommand

Description

As part of #17, this task is to introduce a new down subcommand to op-up that winds down the op-stack defined by the local stack.toml configuration file.

Since this is a destructive action, it should use inquire to prompt the user to confirm running the command.

The logic of winding down a stack based on the config should be abstracted into the Stage Manager orchestrator (doesn't exist yet). This allows the opup cli binary to build the stage manager from the config, and then be able to wind down the stack via a simple down() -> eyre::Result<()> call.

For example

StageManager::from(config).down()?;

The logic behind building a stage manager orchestrator from the stack config is so that it can handle finding existing running stack components based on the configuration. This separates concerns whereby the stack configuration solely handles component and stack configuration while the stage manager can handle orchestrating the stack stages/components.

Since the stage manager .down() call is very minimal, the down subcommand logic can be placed inside cli.rs alongside subcommand dispatching.

feat(stages): support `Reth` L1Client

In the L1 Executor stage, we should add support for the Reth execution client.

match self.l1_client {
L1Client::Geth => self.start_geth().await?,
_ => unimplemented!("l1 client not implemented: {}", self.l1_client),
}

This will require setting up the Dockerfile (and an entrypoint file if necessry) and checking that:

  1. the image is built successfully
  2. the container is created successfully
  3. the container is started successfully
  4. the ports are bound correctly, and the assigned RPC API port is responding

fix(primitives): Monorepo Clone

Description

When executing the directories stage, the monorepo clone fails if the directory already exists. It should only clone the repository if the directory does not exist and gracefully log a warning if an error would be thrown.

Seeing the following output:

Error: Failed to clone [email protected]:ethereum-optimism/optimism.git in "...": fatal: destination path 'optimism' already exists and is not an empty directory.

feat: Component TOMLs

Description

The op_config crate offers a Config TOML that allows you to configure the OP Stack.

While this is useful for stack-wide configuration, op-up needs component-level TOML configs.

TOML is the config of choice to enable for configuration parsing into native rust so configs can be used as a library. This is a backwards-compatible alternative to defining custom dockerfiles for each component, and will allow for #3.

To make the TOMLs backwards-compatible, a field should allow for component TOMLs to reference base docker images or local Dockerfiles.

The TOML could look like the following

[metadata]
name = "challenger-go"
version = "1.1.2"

[command]
git = "[email protected]:ethereum-optimism/optimism.git"
# Default test hardhat deploy key - not safe for production environments
deployer = "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"

[docker]
# The remote docker url will be tried first to fetch the container.
remote = "<remote dockerhub container url>"
# If the remote field is not set, or the fetch fails, the local dockerfile will be referenced.
local = "./Dockerfile.challenger-go"

# Below are inlined docker-file specific fields that are only used if the above remote or local fields are not specified.

[docker.build]
base = "golang:1.19.0-alpine3.15"
dependencies = [
    "make",
    "gcc",
    "musl-dev",
    "linux-headers",
    "git",
    "jq",
    "bash"
]
run = "make op-challenger GOOS=$TARGETOS GOARCH=$TARGETARCH"

[docker.exec]
base = "alpine:3.15"
command = ["/bin/sh", "/op-challenger-go-entrypoint.sh"]

[flags]
l1-eth-rpc = "http://l1:8545"
rollup-rpc = "http://rollup-client:8545"
l2oo-address = "$L2OO_ADDRESS"
dgf-address = "$DGF_ADDRESS"

feat(docker): Docker Feature Flag

Description

Creating this issue as a placeholder - it may be useful/necessary to put all docker-dependent code behind a docker feature flag.

Thinking: the op-composer internally has a Docker bollard reference that we may not want to "leak" to the stages crate unless the docker flag is enabled (could be by default unless necessary).

Effectively, a good start would be to add a docker feature flag to the stages crate and hide all docker-dependent code in the crate behind this flag.

fix(stages): Monorepo Management

Description

Path localization happens in an unsafe way inside individual stage handlers, many of which are redundant. This was an initial port to make space for this nice refactor as a followup.

This ticket is to pull all monorepo directory management and path localization into the Monorepo primitive in a safe way and have the Monorepo be propagated down to individual stages.

feat(bin): Clean Subcommand

Description

As part of #17, this task is to introduce a new clean subcommand to op-up that cleans stack artifacts and any additional generated files.

The logic of cleaning a stack based on the config should be abstracted into the Stage Manager orchestrator (doesn't exist yet). This allows the opup cli binary to build the stage manager from the config, and then be able to clean the stack via a simple clean() -> eyre::Result<()> call.

For example

StageManager::from(config).clean()?;

The logic behind building a stage manager orchestrator from the stack config is so that it can handle finding existing running stack components based on the configuration. This separates concerns whereby the stack configuration solely handles component and stack configuration while the stage manager can handle orchestrating the stack stages/components.

Since this logic should be minimal, it can be placed inside cli.rs alongside subcommand dispatching.

chore(ci): Enforce Default Stack TOML

Description

op-up keeps a default stack.toml available at the repository's top level. This issue is to introduce a ci check that verifies the contents of stack.toml matches the default config. The default config should be generated as a toml and then the files can be diffed.

feat: parse component TOMLs into docker containers

Once we have our stack components laid out as TOML files, we will need to parse them into concrete Docker containers in order to start running, orchestrating and monitoring them.

With Bollard, we can use the Docker::create_container() method to prepare a container for a start operation. This requires parsing all image related data along with the rest of the Config.

chore(docs): Config Documentation

Description

Minimal documentation should be done inline with extensive markdown book docs to avoid duplicate, and out-of-sync documentation.

For this issue, the config crate readme.md file should be removed and minimal inline docs should be added to crates/config/src/lib.rs.

In the future, more extensive documentation will be added to documents in the docs/ mdbook.

feat(bin): Up Subcommand

Description

As part of #17, this task is to move the Stack logic in stack.rs to an up subcommand. Most of the time, op-up will be run without specifying this subcommand since it is redundant to execute op-up up.

The up subcommand itself should have a --devnet flag that can be used to override the local stack.toml and default config for a hard-coded devnet stack configuration.

Since this subcommand will have flags and some additional logic, it should be moved to a new up.rs file. So, just moving the contents of stack.rs to this new file and then dispatching the top-level cli.rs to this handler by default and when the up subcommand is provided.

discussion: remove the need for existing system dependencies

Currently the main README includes this paragraph:

First, make sure you have a few things installed.

- [Rust](https://www.rust-lang.org/tools/install)
- [Docker](https://www.docker.com/)
- [Docker Compose](https://docs.docker.com/compose/)
- [Make](https://www.gnu.org/software/make/)
- [jq](https://jqlang.github.io/jq/)

Ideally op-up should be able to be run on by everyone on a new machine.

A potential solution includes the use of a custom Nix environment.
Never used this tool personally, so I'm also curious to learn and explore it for this use case.

A simpler solution is to just check if pre-requisites are installed (e.g. by using which x or x --version commands) and prompt the user to finish installing the ones that aren't yet on $PATH.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.