From dd13cb4ff591a256867ff188ba9d9c7abfcefeba Mon Sep 17 00:00:00 2001 From: Trantorian1 <114066155+Trantorian1@users.noreply.github.com> Date: Fri, 29 Nov 2024 13:03:08 +0100 Subject: [PATCH] docs(readme): updated `README.md` docs and added Docker Compose support (#399) --- .gitignore | 4 + CHANGELOG.md | 1 + Dockerfile | 2 +- Makefile | 156 ++++++++ README.md | 702 +++++++++++++++++++---------------- compose.yaml | 40 ++ crates/tests/src/rpc/read.rs | 16 +- docker-compose.yml | 48 --- madara-runner.sh | 14 + 9 files changed, 616 insertions(+), 367 deletions(-) create mode 100644 Makefile create mode 100644 compose.yaml delete mode 100644 docker-compose.yml create mode 100755 madara-runner.sh diff --git a/.gitignore b/.gitignore index bf4f3d9f7..a256a077c 100644 --- a/.gitignore +++ b/.gitignore @@ -64,3 +64,7 @@ tmp/ *.info *.profraw + +# Running madara with make and docker compose +.secrets +image.tar.gz diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f1d7434e..7e9649ed0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Next release +- docs(readme): updated README.md docs and added Docker Compose support - fix(log): define RUST_LOG=info by default - fix(tracing): RUST_LOG filtering support - fix(fgw): fetch class diff --git a/Dockerfile b/Dockerfile index b00d362e5..80a7605af 100644 --- a/Dockerfile +++ b/Dockerfile @@ -26,7 +26,7 @@ RUN cargo build --release FROM debian:bookworm # Install runtime dependencies RUN apt-get -y update && \ - apt-get install -y openssl ca-certificates tini &&\ + apt-get install -y openssl ca-certificates tini curl &&\ apt-get autoremove -y; \ apt-get clean; \ rm -rf /var/lib/apt/lists/* diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..36586c433 --- /dev/null +++ b/Makefile @@ -0,0 +1,156 @@ +# ============================================================================ # +# STARKNET NODE RUNNER # +# ============================================================================ # + +define HELP +Madara Node Runner + +Helper for running the starknet Madara node. + +Usage: + make + +Targets: + + [ RUNNING MADARA ] + + Runs Madara, automatically pulling the required image if it is not already + available. Note that it is also required for you to have added the necessary + secrets to `./secrets/`, or the nodes will fail to start. + + - start Starts the Madara node + + [ STOPPING MADARA ] + + Note that this will only pause container execution and not delete it, its + volume or image. + + - stop Stops the Madara node + + [ RESTARTING MADARA ] + + Restarts Madara, possibly cleaning containers, images and volumes in the + process. Note that it is also required for you to have added the necessary + secrets to `./secrets/`, or the nodes will fail to restart. + + - restart Restarts the Madara node + - frestart Perform a full clean and restarts the Madara node + + [ LOGGING MADARA ] + + This will show logging outputs for the Madara container. Defaults to following + the output, to quit. + + - logs View logs for Madara + + [ DOWLOAD DEPENDENCIES ] + + Images are downloaded from the github container registry. Note that to avoid + continuousy downloading images those are exported to a `tar.gz` as artefacts. + + - images Downloads the Madara Docker image + + [ CLEANING DEPENDECIES ] + + Will remove running containers, images and even local db. Use the latter with + care as removing the local db will force a resync from genesys. + + - clean Stop containers and prune images + - clean-db Perform clean and remove local database + - fclean Perform clean-db and remove local images + + [ OTHER COMMANDS ] + + - help Show this help message + +endef +export HELP + +SECRETS := .secrets/rpc_api.secret +DB_PATH := /var/lib/madara + +DOCKER_COMPOSE := docker compose -f compose.yaml +DOCKER_TAG := madara:latest +DOCKER_IMAGE := ghcr.io/madara-alliance/$(DOCKER_TAG) +DOCKER_GZ := image.tar.gz + +# dim white italic +DIM := \033[2;3;37m + +# bold cyan +INFO := \033[1;36m + +# bold green +PASS := \033[1;32m + +# bold red +WARN := \033[1;31m + +RESET := \033[0m + +.PHONY: all +all: help + +.PHONY: help +help: + @echo "$$HELP" + +.PHONY: start +start: images $(SECRETS) + @echo -e "$(DIM)running$(RESET) $(PASS)madara$(RESET)" + @$(DOCKER_COMPOSE) up -d + +.PHONY: stop +stop: + @echo -e "$(DIM)stopping$(RESET) $(WARN)madara$(RESET)" + @$(DOCKER_COMPOSE) stop + +.PHONY: logs +logs: + @echo -e "$(DIM)logs for$(RESET) $(INFO)madara$(RESET)"; + @$(DOCKER_COMPOSE) logs -f -n 100 madara; + +.PHONY: images +images: $(DOCKER_GZ) + +$(DOCKER_GZ): + @echo -e "$(DIM)downloading$(RESET) $(PASS)madara$(RESET)" + @docker pull $(DOCKER_IMAGE) + @docker tag $(DOCKER_IMAGE) $(DOCKER_TAG) + @docker rmi $(DOCKER_IMAGE) + @docker image save -o $(DOCKER_GZ) $(DOCKER_TAG) + +.PHONY: clean +clean: stop + @echo -e "$(DIM)pruning containers$(RESET)" + @docker container prune -f + @echo -e "$(DIM)pruning images$(RESET)" + @docker image prune -f + @echo -e "$(WARN)images cleaned$(RESET)" + +.PHONY: clean-db +clean-db: + @echo -e "$(WARN)This action will result in irrecoverable loss of data!$(RESET)" + @echo -e "$(DIM)Are you sure you want to proceed?$(RESET) $(PASS)[y/N] $(RESET)" && \ + read ans && \ + case "$$ans" in \ + [yY]*) true;; \ + *) false;; \ + esac + @make --silent clean + @echo -e "$(DIM)removing madara database on host$(RESET)" + @rm -rf $(DB_PATH); + +.PHONY: fclean +fclean: clean-db + @echo -e "$(DIM)removing local images tar.gz$(RESET)" + @rm -rf $(DOCKER_GZ) + @echo -e "$(WARN)artefacts cleaned$(RESET)" + +.PHONY: restart +restart: clean + @make --silent start + +.PHONY: frestart +frestart: fclean + @make --silent start diff --git a/README.md b/README.md index bc2fbaabe..9a00d483d 100644 --- a/README.md +++ b/README.md @@ -23,368 +23,307 @@ Madara is a powerful Starknet client written in Rust. ## Table of Contents -- ⬇️ Installation +- ⬇️ [Installation](#%EF%B8%8F-installation) - [Run from Source](#run-from-source) - [Run with Docker](#run-with-docker) -- ⚙️ Configuration +- ⚙️ [Configuration](#%EF%B8%8F-configuration) - [Basic Command-Line Options](#basic-command-line-options) - - [Advanced Command-Line Options](#advanced-command-line-options) -- 🌐 Interactions + - [Environment variables](#environment-variables) +- 🌐 [Interactions](#-interactions) - [Supported JSON-RPC Methods](#supported-json-rpc-methods) + - [Madara-specific JSON-RPC Methods](#madara-specific-json-rpc-methods) - [Example of Calling a JSON-RPC Method](#example-of-calling-a-json-rpc-method) -- Supported Features -- 👍 Contribute +- ✅ [Supported Features](#-supported-features) + - [Starknet Compliant](#starknet-compliant) + - [Feeder-Gateway State Synchronization](#feeder-gateway-state-synchronization) + - [State Commitment Computation](#state-commitment-computation) +- 💬 [Get in touch](#-get-in-touch) + - [Contributing](#contributing) + - [Partnerships](#partnerships) ## ⬇️ Installation -### Run from Source - -1. **Install dependencies** - - Ensure you have the necessary dependencies: - - | Dependency | Version | Installation | - | ---------- | ---------- | ---------------------------------------------------------------------------------------- | - | Rust | rustc 1.81 | `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \| sh` | - | Clang | Latest | `sudo apt-get install clang` | - | Scarb | v2.8.2 | `curl --proto '=https' --tlsv1.2 -sSf https://docs.swmansion.com/scarb/install.sh \| sh` | - - Clone the Madara repository: - - ```bash - cd - git clone https://github.com/madara-alliance/madara . - ``` - -2. **Build Program** - - Choose between different build modes: - - - **Debug** (fastest build mode, but lower performance, for testing purposes only): - - ```bash - cargo build - ``` - - - **Release** (recommended build mode): - - ```bash - cargo build --release - ``` - - - **Production** (recommended for production performance): - - ```bash - cargo build --profile=production - ``` - -3. **Run Madara** - - Start the Madara client with a basic set of arguments depending on your chosen mode: - - **Full Node** - - ```bash - cargo run --release -- \ - --name Madara \ - --full \ - --base-path /var/lib/madara \ - --network mainnet \ - --l1-endpoint ${ETHEREUM_API_URL} - ``` - - **Sequencer** +[⬅️ back to top](#-madara-starknet-client) - ```bash - cargo run --release -- \ - --name Madara \ - --sequencer \ - --base-path /var/lib/madara \ - --preset test \ - --l1-endpoint ${ETHEREUM_API_URL} - ``` - - **Devnet** - - ```bash - cargo run --release -- \ - --name Madara \ - --devnet \ - --base-path /var/lib/madara \ - --preset test - ``` - - > ℹ️ **Info:** We recommend you to head to the [Configuration](https://docs.madara.build/fundamentals/configuration) - > section to customize your node parameters. - > ℹ️ **Info:** If you don't have an L1 endpoint URL, we recommend you refer to the relevant - > section to obtain one. - -### Run with Docker - -1. **Install Docker** - - Ensure you have Docker installed on your machine. Once you have Docker installed, you can run Madara using the available Docker images. - - ```bash - docker run -d \ - --name Madara \ - --full - -p 9944:9944 \ - -v /var/lib/madara:/var/lib/madara \ - madara:latest \ - --base-path /var/lib/madara \ - --network mainnet \ - --l1-endpoint ${ETHEREUM_API_URL} - ``` - - > ℹ️ **Info:** This is a default configuration for a Full Node on Starknet mainnet. - > For more information on possible configurations, please visit the - > [Configuration](https://docs.madara.build/fundamentals/configuration) section. - > ⚠️ **Warning:** Make sure to change the volume `-v` of your container if you change the `--base-path`. - > ℹ️ **Info:** If you don't have an L1 endpoint URL, we recommend you refer to the relevant section to obtain one. - -2. **Check Logs** - - ```bash - docker logs -f Madara - ``` +### Run from Source - > ℹ️ **Info:** Now you can head to the [Metrics](https://docs.madara.build/monitoring/grafana) - > section to deploy a Grafana and Prometheus dashboard. +#### 1. Install dependencies -## ⚙️ Configuration +Ensure you have all the necessary dependencies available on your host system. -### Command-Line Options +| Dependency | Version | Installation | +| ---------- | ---------- | ----------------------------------------------------------------- | +| Rust | rustc 1.81 | `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \| sh` | +| Clang | Latest | `sudo apt-get install clang` | +| Openssl | 0.10 | `sudo apt install openssl` | -For a comprehensive list of command-line options: +Once all dependencies are satisfied, you can clone the Madara repository: ```bash -cargo run -- --help +cd +git clone https://github.com/madara-alliance/madara . ``` -Below are some essential command-line options and a categorized list of advanced configurations: - -#### Basic Command-Line Options - -Here are the recommended options for a quick and simple configuration of your Madara client: - -- **`--name `**: The human-readable name for this node. It's used as the network node name. - -- **`--base-path `**: Set the directory for Starknet data (default is `/tmp/madara`). - -- **`--full`**: The mode of your Madara client (either `--sequencer`, `--full`, or `devnet`). +#### 2. Build Madara -- **`--l1-endpoint `**: Specify the Layer 1 endpoint the node will verify its state from. +You can choose between different build modes: -- **`--rpc-port `**: Specify the JSON-RPC server TCP port. +- **Debug** (low performance, fastest builds, _for testing purposes only_): -- **`--rpc-cors `**: Specify browser origins allowed to access the HTTP & WS RPC servers. + ```bash + cargo build + ``` -- **`--rpc-external`**: Listen to all RPC interfaces. Default is local. +- **Release** (fast performance, slower build times): -> ℹ️ **Info:** For more information regarding synchronization configuration, please refer to the -> [Configuration](https://docs.madara.build/fundamentals/configuration) section. + ```bash + cargo build --release + ``` -### Advanced Command-Line Options +- **Production** (fastest performance, _very slow build times_): -Toggle details for each namespace to view additional settings: + ```bash + cargo build --profile=production + ``` -
-Network - -- **`-n, --network `**: The network type to connect to. - - - [default: mainnet] - - Possible values: - - - `mainnet`: The main network (mainnet). Alias: main - - `testnet`: The test network (testnet). Alias: sepolia - - `integration`: The integration network - - `devnet`: A devnet for local testing - -- **`--l1-endpoint `**: Specify the Layer 1 RPC endpoint for state verification. - -- **`--gateway-key `**: Gateway API key to avoid rate limiting (optional). - -- **`--sync-polling-interval `**: Polling interval in seconds. - - - [default: 4] - -- **`--pending-block-poll-interval `**: Pending block polling interval in seconds. +#### 3. Run Madara - - [default: 2] +Start the Madara client with a basic set of arguments depending on your chosen mode: -- **`--no-sync-polling`**: Disable sync polling. +#### Full Node -- **`--n-blocks-to-sync `**: Number of blocks to sync, useful for benchmarking. - -- **`--unsafe-starting-block `**: Start syncing from a specific block. May cause database inconsistency. - -- **`--sync-disabled`**: Disable the sync service. - -- **`--sync-l1-disabled`**: Disable L1 sync service. - -- **`--gas-price-sync-disabled`**: Disable the gas price sync service. - -- **`--gas-price-poll-ms `**: Interval in milliseconds for the gas price sync service to fetch the gas price. - - [default: 10000] - -
- -
-RPC +Synchronizes the state of the chain from genesis. -- **`--rpc-disabled`**: Disable the RPC server. +```bash +cargo run --release -- \ + --name Madara \ + --full \ + --base-path /var/lib/madara \ + --network mainnet \ + --l1-endpoint ${ETHEREUM_API_URL} +``` -- **`--rpc-external`**: Listen to all network interfaces. +#### Sequencer -- **`--rpc-methods `**: RPC methods to expose. +Produces new blocks for other nodes to synchronize. - - [default: auto] +```bash +cargo run --release -- \ + --name Madara \ + --sequencer \ + --base-path /var/lib/madara \ + --preset test \ + --l1-endpoint ${ETHEREUM_API_URL} +``` - Possible values: +#### Devnet - - `auto`: Expose all methods if RPC is on localhost, otherwise serve only safe methods. - - `safe`: Allow only a safe subset of RPC methods. - - `unsafe`: Expose all RPC methods (even potentially unsafe ones). +A node in a private local network. -- **`--rpc-rate-limit `**: RPC rate limiting per connection. +```bash +cargo run --release -- \ + --name Madara \ + --devnet \ + --base-path /var/lib/madara \ + --preset test +``` -- **`--rpc-rate-limit-whitelisted-ips `**: Disable RPC rate limiting for specific IP addresses or ranges. +> [!NOTE] +> Head to the [Configuration](#%EF%B8%8F-configuration) section to learn more about +> customizing your node. -- **`--rpc-rate-limit-trust-proxy-headers`**: Trust proxy headers for disabling rate limiting in reverse proxy setups. +#### 4. Presets -- **`--rpc-max-request-size `**: Maximum RPC request payload size for both HTTP and WebSockets. +You can use cli presets for certain common node configurations, for example +enabling rpc endpoints: - - [default: 15] +```bash +cargo run --release -- \ + --name Madara \ + --full \ + --preset mainnet \ + --rpc +``` -- **`--rpc-max-response-size `**: Maximum RPC response payload size for both HTTP and WebSockets. +...or the madara [feeder gateway](#feeder-gateway-state-synchronization): - - [default: 15] +```bash +cargo run --release -- \ + --name Madara \ + --full \ + --preset mainnet \ + --fgw +``` -- **`--rpc-max-subscriptions-per-connection `**: Maximum concurrent subscriptions per connection. +--- - - [default: 1024] +### Run with Docker -- **`--rpc-port `**: The RPC port to listen on. +#### 1. Manual Setup - - [default: 9944] +| Dependency | Version | Installation | +| ---------- | ------- | ---------------------------------------------------------------- | +| Docker | Latest | [Official instructions](https://docs.docker.com/engine/install/) | -- **`--rpc-max-connections `**: Maximum number of RPC server connections at a given time. +Once you have Docker installed, you will need to pull the madara image from +the github container registry (ghr): - - [default: 100] +```bash +docker pull ghcr.io/madara-alliance/madara:latest +docker tag ghcr.io/madara-alliance/madara:latest madara:latest +docker rmi ghcr.io/madara-alliance/madara:latest +``` -- **`--rpc-disable-batch-requests`**: Disable RPC batch requests. +You can then launch madara as follows: -- **`--rpc-max-batch-request-len `**: Limit the max length for an RPC batch request. +```bash +docker run -d \ + -p 9944:9944 \ + -v /var/lib/madara:/tmp/madara \ + --name Madara \ + madara:latest \ + --name Madara \ + --full \ + --network mainnet \ + --l1-endpoint ${ETHEREUM_API_URL} +``` -- **`--rpc-cors `**: Specify browser origins allowed to access the HTTP & WebSocket RPC servers. +To display the node's logs, you can use: -- **`--rpc-message-buffer-capacity-per-connection `**: Maximum number of messages in memory per connection. - - [default: 64] +```bash +docker logs -f -n 100 Madara +``` -
+> [!WARNING] +> Make sure to change the volume `-v` of your container if ever you update +> `--base-path`. -
-Database +#### 2. Using the project Makefile -- **`--base-path `**: The path where Madara will store the database. +Alternatively, you can use the provided Makefile and `compose.yaml` to +simplify this process. - - [default: /tmp/madara] +| Dependency | Version | Installation | +| -------------- | ------- | ----------------------------------------------------------------- | +| Docker Compose | Latest | [Official instructions](https://docs.docker.com/compose/install/) | +| Gnu Make | Latest | `sudo apt install make` | -- **`--backup-dir `**: Directory for backups. +Once you have all the dependencies installed, start by saving your rpc key +to a `.secrets` forlder: -- **`--backup-every-n-blocks `**: Periodically create a backup. +```bash +mkdir .secrets +echo *** .secrets/rpc_api.secret +``` -- **`--restore-from-latest-backup`**: Restore the database from the latest backup version. +Then, run madara with the following commands: -
- -
-Block Production +```bash +make start # This will automatically pull the madara image if not available +make logs # Displays the last 100 lines of logs +make stop # Stop the madara node +make clean-db # Removes the madara db, including files on the host +make restart # Restarts the madara node +``` -- **`--block-production-disabled`**: Disable the block production service. +> [!IMPORTANT] +> By default, `make start` will try and restart Madara indefinitely if it is +> found to be unhealthy using [docker autoheal](https://github.com/willfarrell/docker-autoheal). +> This is done by checking the availability of `http://localhost:9944/health`, +> which means your container will be marked as `unhealthy` and restart if you +> have disabled the RPC service! You can run `watch docker ps` to monitor the +> health of your containers. -- **`--devnet`**: Launch in block production mode, with devnet contracts. +To change runtime arguments, you can update the script in `madara-runner.sh`: -- **`--devnet-contracts `**: Create this number of contracts in the genesis block for the devnet configuration. +```bash +#!/bin/sh +export RPC_API_KEY=$(cat $RPC_API_KEY_FILE) + +./madara \ + --name madara \ + --network mainnet \ + --rpc-external \ + --rpc-cors all \ + --full \ + --l1-endpoint $RPC_API_KEY +``` - - [default: 10] +For more information, run: -- **`--override-devnet-chain-id`**: Launch a devnet with a production chain ID. +```bash +make help +``` -- **`--authority`**: Enable authority mode; the node will run as a sequencer and try to produce its own blocks. +> [!TIP] +> When running Madara from a docker container, make sure to set options such +> as `--rpc-external`, `--gateway-external` and `--rpc-admin-external` so as +> to be able to access these services from outside the container. -
+## ⚙️ Configuration -
-Metrics +[⬅️ back to top](#-madara-starknet-client) -- **`--telemetry`**: Enable connection to the Madara telemetry server. +For a comprehensive list of all command-line options, check out: -- **`--telemetry-url `**: The URL of the telemetry server with verbosity level. +```bash +cargo run -- --help +``` - - [default: "wss://starknodes.com/submit 0"] +Or if you are using docker, simply: -- **`--prometheus-port `**: The port used by the Prometheus RPC service. +```bash +docker run madara:latest --help +``` - - [default: 9615] +--- -- **`--prometheus-external`**: Listen on all network interfaces for Prometheus. +### Basic Command-Line Options -- **`--prometheus-disabled`**: Disable the Prometheus service. +Here are some recommended options to get up and started with your Madara client: -
+| Option | About | +| -------------------------- | ------------------------------------------------------------------------------ | +| **`--name `** | The human-readable name for this node. It's used as the network node name. | +| **`--base-path `** | Sets the database location for Madara (default is`/tmp/madara`) | +| **`--full`** | The mode of your Madara client (either `--sequencer`, `--full`, or `--devnet`) | +| **`--l1-endpoint `** | The Layer 1 endpoint the node will verify its state from | +| **`--rpc-port `** | The JSON-RPC server TCP port, used to receive requests | +| **`--rpc-cors `** | Browser origins allowed to make calls to the RPC servers | +| **`--rpc-external`** | Exposes the rpc service on `0.0.0.0` | -> ℹ️ **Info:** Note that not all parameters may be referenced here. -> Please refer to the `cargo run -- --help` command for the full list of parameters. +--- ### Environment Variables -Set up your node's environment variables using the `MADARA_` prefix. For example: +Each cli argument has its own corresponding environment variable you can set to +change its value. For example: -- `MADARA_BASE_PATH=/path/to/data` +- `MADARA_BASE_PATH=/path/to/db` - `MADARA_RPC_PORT=1111` -These variables allow you to adjust the node's configuration without using command-line arguments. If the command-line -argument is specified then it takes precedent over the environment variable. - -> [!CAUTION] -> Environment variables can be visible beyond the current process and are not -> encrypted. You should take special care when setting _secrets_ through -> environment variables, such as `MADARA_L1_ENDPOINT` or `MADARA_GATEWAY_KEY` - -### Configuration File - -You can use a JSON, TOML, or YAML file to structure your configuration settings. -Specify your configuration file on startup with the `-c` option. Here's a basic example in JSON format: +These variables allow you to adjust the node's configuration without using +command-line arguments, which can be useful in CI pipelines or with docker. -```json -{ - "name": "Deoxys", - "base_path": "../deoxys-db", - "network": "mainnet", - "l1_endpoint": "l1_key_url", - "rpc_port": 9944, - "rpc_cors": "*", - "rpc_external": true, - "prometheus_external": true -} -``` +> [!NOTE] +> If the command-line argument is specified then it takes precedent over the +> environment variable. -> 💡 **Tip:** Review settings carefully for optimal performance and refer to Starknet's -> official documentation for detailed configuration guidelines. +## 🌐 Interactions -Always test your configuration in a non-production environment before rolling it out to a live node to prevent downtime -and other potential issues. +[⬅️ back to top](#-madara-starknet-client) -> ℹ️ **Info:** For a custom chain configuration, you can refer to the configuration section of chain operator deployments. +Madara fully supports all the JSON-RPC methods as of the latest version of the +Starknet mainnet official [JSON-RPC specs](https://github.com/starkware-libs/starknet-specs). +These methods can be categorized into three main types: Read-Only Access Methods, +Trace Generation Methods, and Write Methods. They are accessible through port +**9944** unless specified otherwise with `--rpc-port`. -## 🌐 Interactions +> [!TIP] +> You can use the special `rpc_methods` call to view a list of all the methods +> which are available on an endpoint. -Madara fully supports all the JSON-RPC methods as specified in the Starknet mainnet official [JSON-RPC specs](https://github.com/starkware-libs/starknet-specs). -These methods can be categorized into three main types: Read-Only Access Methods, Trace Generation Methods, and Write Methods. +--- ### Supported JSON-RPC Methods @@ -397,8 +336,8 @@ Here is a list of all the supported methods with their current status: | ------ | ------------------------------------------ | | ✅ | `starknet_specVersion` | | ✅ | `starknet_getBlockWithTxHashes` | -| ✅ | `starknet_getBlockWithReceipts` | | ✅ | `starknet_getBlockWithTxs` | +| ✅ | `starknet_getBlockWithReceipts` | | ✅ | `starknet_getStateUpdate` | | ✅ | `starknet_getStorageAt` | | ✅ | `starknet_getTransactionStatus` | @@ -418,6 +357,9 @@ Here is a list of all the supported methods with their current status: | ✅ | `starknet_syncing` | | ✅ | `starknet_getEvents` | | ✅ | `starknet_getNonce` | +| ✅ | `starknet_getCompiledCasm` (v0.8.0) | +| 🚧 | `starknet_getMessageStatus` (v0.8.0) | +| 🚧 | `starknet_getStorageProof` (v0.8.0) | @@ -443,72 +385,208 @@ Here is a list of all the supported methods with their current status: -> ℹ️ **Info:** Madara currently supports the latest [JSON-RPC specs](https://github.com/starkware-libs/starknet-specs) up to version v0.7.1. +
+ Websocket Methods + +| Status | Method | +| ------ | ------------------------------------------------ | +| ✅ | `starknet_unsubscribe` (v0.8.0) | +| ✅ | `starknet_subscribeNewHeads` (v0.8.0) | +| ❌ | `starknet_subscribeEvents` (v0.8.0) | +| ❌ | `starknet_subscribeTransactionStatus` (v0.8.0) | +| ❌ | `starknet_subscribePendingTransactions` (v0.8.0) | +| ❌ | `starknet_subscriptionReorg` (v0.8.0) | + +
+ +> [!IMPORTANT] +> Write methods are forwarded to the Sequencer and are not executed by Madara. +> These might fail if you provide the wrong arguments or in case of a +> conflicting state. Make sure to refer to the +> [Starknet JSON-RPC specs](https://github.com/starkware-libs/starknet-specs) +> for a list of potential errors. + +### Madara-specific JSON-RPC Methods + +As well as the official RPC methods, Madara also supports its own set of custom +extensions to the starknet specs. These are referred to as `admin` methods and +are exposed on a separate port **9943** unless specified otherwise with +`--rpc-admin-port`. + +
+ Write Methods + +| Method | About | +| -------------------------------- | ------------------------------------------------- | +| `madara_addDeclareV0Transaction` | Adds a legacy Declare V0 Transaction to the state | + +
+ +
+ Status Methods + +| Method | About | +| -------------------- | ---------------------------------------------------- | +| `madara_ping` | Return the unix time at which this method was called | +| `madara_shutdown` | Gracefully stops the running node | +| `madara_rpcDisable` | Disables user-facing rpc services | +| `madara_rpcEnable` | Enables user-facing rpc services | +| `madara_rpcRestart` | Restarts user-facing rpc services | +| `madara_syncDisable` | Disables l1 and l2 sync services | +| `madara_syncEnable` | Enables l1 and l2 sync services | +| `madara_syncRestart` | Restarts l1 and l2 sync services | + +
+ +
+ Websocket Methods + +| Method | About | +| -------------- | -------------------------------------------------- | +| `madara_pulse` | Periodically sends a signal that the node is alive | + +
+ +> [!CAUTION] +> These methods are exposed on `locahost` by default for obvious security +> reasons. You can always exposes them externally using `--rpc-admin-external`, +> but be _very careful_ when doing so as you might be compromising your node! +> Madara does not do **any** authorization checks on the caller of these +> methods and instead leaves it up to the user to set up their own proxy to +> handle these situations. + +--- ### Example of Calling a JSON-RPC Method -Here is an example of how to call a JSON-RPC method using Madara: +You can use any JSON-RPC client to interact with Madara, such as `curl`, +`httpie`, `websocat` or any client sdk in your preferred programming language. +For more detailed information on how to call each method, please refer to the +[Starknet JSON-RPC specs](https://github.com/starkware-libs/starknet-specs). + +#### Http RPC -```json +| Dependency | Version | Installation | +| ---------- | ------- | ----------------------- | +| Curl | Latest | `sudo apt install curl` | + +Here is an example of how to call a JSON-RPC method using Madara. Before running +the bellow code, make sure you have a node running with rpc enabled on port 9944 +(this is the default configuration). + +> [!IMPORTANT] +> Madara currently defaults to `v0.7.1` for its rpc calls. To access methods +> in other or more recent versions, add `rpc/v*_*_*/` to your rpc url. This +> Also works for websocket methods. + +```bash +curl --location 'localhost:9944'/v0_7_1/ \ + --header 'Content-Type: application/json' \ + --data '{ + "jsonrpc": "2.0", + "method": "rpc_methods", + "params": [], + "id": 1 + }' | jq --sort-keys +``` + +You should receive something like the following: + +```bash { + "id": 1, "jsonrpc": "2.0", - "method": "starknet_getBlockWithTxHashes", - "params": { - "block_id": "latest" - }, - "id": 1 + "result": { + "methods": [ + "rpc/V0_7_1/starknet_addDeclareTransaction", + "rpc/V0_7_1/starknet_addDeployAccountTransaction", + "rpc/V0_7_1/starknet_addInvokeTransaction", + ... + "rpc/V0_8_0/starknet_traceBlockTransactions", + "rpc/V0_8_0/starknet_traceTransaction", + "rpc/V0_8_0/starknet_unsubscribe", + "rpc/rpc_methods" + ] + } } ``` -You can use any JSON-RPC client to interact with the Madara node, such as `curl`, `httpie`, -or a custom client in your preferred programming language. -For more detailed information and examples on each method, please refer to the [Starknet JSON-RPC specs](https://github.com/starkware-libs/starknet-specs). +#### Websocket RPC + +| Dependency | Version | Installation | +| ---------- | ------- | --------------------------------------------------------------------------------------- | +| Websocat | Latest | [Official instructions](https://github.com/vi/websocat?tab=readme-ov-file#installation) | + +Websockets methods are enabled by default and are accessible through the same +port as http RPC methods. Here is an example of how to call a JSON-RPC method +using `websocat`. + +```bash +(echo '{"jsonrpc":"2.0","method":"starknet_subscribeNewHeads","params":{"block_id":"latest"},"id":1}'; cat -) | \ +websocat -v ws://localhost:9944/rpc/v0_8_0 +``` + +> [!TIP] +> This command and the strange use of `echo` in combination with `cat` is just a +> way to start a websocket stream with `websocat` while staying in interactive +> mode, meaning you can still enter other websocket requests. + +This will display header information on each new block synchronized. Use +`Ctrl-C` to stop the subscription. Alternatively, you can achieve the same +result more gracefully by calling `starknet_unsubscribe`. Paste the following +into the subscription stream: + +```bash +{ "jsonrpc": "2.0", "method": "starknet_unsubscribe", "params": ["your-subscription-id"], "id": 1 } +``` -> ⚠️ **Warning:** Write methods are forwarded to the Sequencer for execution. -> Ensure you handle errors appropriately as per the JSON-RPC schema. +Where `you-subscription-id` corresponds to the value of the `subscription` field +which is returned with each websocket response. -## 📊 Analytics +## ✅ Supported Features -Madara comes packed with OTEL integration, supporting export of traces, metrics and logs. +[⬅️ back to top](#-madara-starknet-client) -- OTEL version `v0.25.0` -- `Trace` and `Logs` are implemented using [tokio tracing](https://github.com/tokio-rs/tracing). -- `Metric` uses OTEL provided metrics. +### Starknet compliant -### Basic Command-Line Option +Madara is compliant with the latest `v0.13.2` version of Starknet and `v0.7.1` +JSON-RPC specs. You can find out more about this in the [interactions](#-interactions) +section or at the official Starknet [JSON-RPC specs](https://github.com/starkware-libs/starknet-specs). -- **`--analytics-collection-endpoint `**: Endpoint for OTLP collector, if not provided then OTLP is not enabled. -- **`--analytics-service-name `**: Allows to customize the collection service name. +### Feeder-Gateway State Synchronization -#### Setting up Signoz +Madara supports its own implementation of the Starknet feeder gateway, which +allows nodes to synchronize state from each other at much faster speeds than +a regular sync. -- Signoz Dashboard JSONs are provided at `infra/Signoz/dashboards`. -- Signoz Docker Standalone can be setup following this [guide](https://signoz.io/docs/install/docker/). -- Ensure to configure the correct service_name after importing the json to the dashboard. +> [!NOTE] +> Starknet does not currently have a specification for its feeder-gateway +> protocol, so despite our best efforts at output parity, you might still notice +> some discrepancies between official feeder gateway endpoints and our own +> implementation. Please let us know about if you encounter this by +> [raising an issue](https://github.com/madara-alliance/madara/issues/new/choose) -## ✔ Supported Features +### State Commitment Computation -Madara offers numerous features and is constantly improving to stay at the cutting edge of Starknet technology. +Madara supports merkelized state verification through its own implementation of +Besu Bonsai Merkle Tries. See the [bonsai lib](https://github.com/madara-alliance/bonsai-trie). +You can read more about Starknet Block structure and how it affects state +commitment [here](https://docs.starknet.io/architecture-and-concepts/network-architecture/block-structure/). -- **Starknet Version**: `v0.13.2` -- **JSON-RPC Version**: `v0.7.1` -- **Feeder-Gateway State Synchronization** -- **State Commitment Computation** -- **L1 State Verification** -- **Handling L1 and L2 Reorgs** +## 💬 Get in touch -Each feature is designed to ensure optimal performance and seamless integration with the Starknet ecosystem. +[⬅️ back to top](#-madara-starknet-client) -## 👍 Contribute +### Contributing For guidelines on how to contribute to Madara, please see the [Contribution Guidelines](https://github.com/madara-alliance/madara/blob/main/CONTRIBUTING.md). -## 🤝 Partnerships +### Partnerships To establish a partnership with the Madara team, or if you have any suggestions or special requests, feel free to reach us on [Telegram](https://t.me/madara-alliance). -## ⚠️ License +### License Madara is open-source software licensed under the [Apache-2.0 License](https://github.com/madara-alliance/madara/blob/main/LICENSE). diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 000000000..8e50fea0e --- /dev/null +++ b/compose.yaml @@ -0,0 +1,40 @@ +name: madara_runner + +services: + madara: + image: madara:latest + container_name: "madara_runner" + cpus: "4.0" + mem_limit: "16gb" + ports: + - 9944:9944 + labels: + - "autoheal=true" + environment: + - RPC_API_KEY_FILE=/run/secrets/rpc_api_key + secrets: + - rpc_api_key + volumes: + - /var/lib/madara:/tmp/madara + - ./madara-runner.sh:/usr/local/bin/runner.sh:ro + entrypoint: + - /usr/local/bin/runner.sh + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:9944/health"] + interval: 10s + timeout: 5s + retries: 3 + start_period: 10s + restart: on-failure:3 + + autoheal: + image: willfarrell/autoheal:latest + tty: true + restart: always + volumes: + - /etc/localtime:/etc/localtime:ro + - /var/run/docker.sock:/var/run/docker.sock + +secrets: + rpc_api_key: + file: .secrets/rpc_api.secret diff --git a/crates/tests/src/rpc/read.rs b/crates/tests/src/rpc/read.rs index c8fa59716..2dfdfb802 100644 --- a/crates/tests/src/rpc/read.rs +++ b/crates/tests/src/rpc/read.rs @@ -41,12 +41,12 @@ mod test_rpc_read_calls { } impl Drop for SharedMadaraInstance { fn drop(&mut self) { - let mut guard = MADARA_HANDLE_COUNT.lock().expect("poisoned lock"); - *guard -= 1; - if *guard == 0 { - // :/ - tokio::task::spawn_blocking(|| *MADARA.blocking_lock() = None); - } + // let mut guard = MADARA_HANDLE_COUNT.lock().expect("poisoned lock"); + // *guard -= 1; + // if *guard == 0 { + // // :/ + // tokio::task::spawn_blocking(|| *MADARA.blocking_lock() = None); + // } } } #[allow(clippy::await_holding_lock)] @@ -650,6 +650,10 @@ mod test_rpc_read_calls { }; let expected_txn_status = TransactionStatus::AcceptedOnL2(TransactionExecutionStatus::Succeeded); + // TODO: The shared madara state needs a rework as we only run these + // tests with `--test-threads=1`. These tests + tokio::task::spawn_blocking(|| *MADARA.blocking_lock() = None); + assert_eq!(txn_status, expected_txn_status); } diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 1ded3272c..000000000 --- a/docker-compose.yml +++ /dev/null @@ -1,48 +0,0 @@ -services: - madara: - build: - context: ./ - dockerfile: Dockerfile - container_name: madara - restart: unless-stopped - ports: - - "${RPC_PORT:-9944}:9944" - volumes: - - $HOME/madara:/var/lib/madara - entrypoint: ["tini", "--"] - command: - [ - "/usr/local/bin/madara", - "--base-path", - "/var/lib/madara", - "--network", - "main", - "--l1-endpoint", - "${L1_ENDPOINT}", - ] - profiles: - - mainnet - - madara-testnet: - build: - context: ./ - dockerfile: Dockerfile - container_name: madara-testnet - restart: unless-stopped - ports: - - "${RPC_PORT:-9944}:9944" - volumes: - - $HOME/madara-testnet:/var/lib/madara-testnet - entrypoint: ["tini", "--"] - command: - [ - "/usr/local/bin/madara", - "--base-path", - "/var/lib/madara-testnet", - "--network", - "test", - "--l1-endpoint", - "${L1_ENDPOINT}", - ] - profiles: - - testnet diff --git a/madara-runner.sh b/madara-runner.sh new file mode 100755 index 000000000..e38992a69 --- /dev/null +++ b/madara-runner.sh @@ -0,0 +1,14 @@ +#!/bin/sh +if [ -f "$RPC_API_KEY_FILE" ]; then + export RPC_API_KEY=$(cat "$RPC_API_KEY_FILE") +else + echo "Error: RPC_API_KEY_FILE not found!" >&2 + exit 1 +fi + +tini -- ./madara \ + --name madara \ + --network mainnet \ + --rpc-external \ + --full \ + --l1-endpoint $RPC_API_KEY