diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index 7d3b4df725..01ffa5dc48 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -12,7 +12,7 @@ body: label: Version Information description: Please provide versions of all relevant components placeholder: | - Rollkit: + ev-node: Execution Implementation: validations: required: true @@ -112,7 +112,7 @@ body: description: | Please provide relevant logs from different components: - Node logs - - Rollkit logs + - Ev-node logs - DA logs - Sequencer logs - Execution logs diff --git a/.github/workflows/build_docs.yml b/.github/workflows/build_docs.yml new file mode 100644 index 0000000000..d8f1a73e44 --- /dev/null +++ b/.github/workflows/build_docs.yml @@ -0,0 +1,28 @@ +name: Build VitePress Site +permissions: + contents: read + +on: + push: + branches: [main] + paths: + - "./docs" + pull_request: + paths: + - "./docs" + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: yarn # or pnpm / npm + - name: Install dependencies + run: yarn install # or pnpm install / npm ci + - name: Build with VitePress + run: yarn build # or pnpm build / npm build diff --git a/.github/workflows/deploy_docs.yml b/.github/workflows/deploy_docs.yml new file mode 100644 index 0000000000..713cf34c76 --- /dev/null +++ b/.github/workflows/deploy_docs.yml @@ -0,0 +1,51 @@ +# Sample workflow for building and deploying a VitePress site to GitHub Pages +# +name: Deploy VitePress site to Pages + +on: + # Runs on pushes targeting the `main` branch. Change this to `master` if you're + # using the `master` branch as the default branch. + push: + branches: [main] + paths: + - "./docs" + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: write-all + +# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. +# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. +concurrency: + group: pages + cancel-in-progress: false + +jobs: + # Build job + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Not needed if lastUpdated is not enabled + # - uses: pnpm/action-setup@v2 # Uncomment this if you're using pnpm + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: yarn # or pnpm / npm + - name: Setup Pages + uses: actions/configure-pages@v5 + - name: Install dependencies + run: yarn install # or pnpm install / npm ci + - name: Build with VitePress + run: yarn build # or pnpm build / npm build + - name: Deploy to GitHub Pages + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./.vitepress/dist + cname: ev.xyz diff --git a/.github/workflows/preview_docs.yml b/.github/workflows/preview_docs.yml new file mode 100644 index 0000000000..5b5489121b --- /dev/null +++ b/.github/workflows/preview_docs.yml @@ -0,0 +1,45 @@ +name: Deploy PR previews + +on: + # This workflow requires pull_request and won't work with pull_request_target + # due to github permissions + pull_request: + types: + - opened + - reopened + - synchronize + - closed + paths: + - "./docs" + +concurrency: preview-${{ github.ref }} + +jobs: + deploy-preview: + if: github.actor != 'dependabot[bot]' + runs-on: ubuntu-latest + permissions: write-all + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: yarn + + - name: Install dependencies + run: yarn install --frozen-lockfile + + - name: Build with Base URL + run: BASE='/docs-preview/pr-${{ github.event.number }}/' yarn build + + - name: Deploy preview + uses: rossjrw/pr-preview-action@v1 + with: + source-dir: .vitepress/dist + deploy-repository: evstack/docs-preview + token: ${{ secrets.PREVIEW_DEPLOY }} + preview-branch: main + umbrella-dir: . diff --git a/.gitignore b/.gitignore index f2bb112446..7ee3f22dd0 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,14 @@ build .DS_Store coverage.out execution/evm/jwttoken -target \ No newline at end of file +target + +docs/.vitepress/dist +node_modules +docs/.vitepress/cache +*.log +*.tgz +.idea +.temp +.vite_opt_cache +.vscode diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 360c41d6fa..b0b7db2af2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,7 +2,7 @@ ## Finding an issue -GitHub issues are used to track the work associated with Rollkit. That's where you can find things to work on. +GitHub issues are used to track the work associated with Evolve. That's where you can find things to work on. Issue labels have been used to help designate the priority, status and beginner-friendliness of various issues. Here are some of the ones that are most relevant to finding a good issue to work on: diff --git a/README.md b/README.md index 55c6015eea..3b91cefa55 100644 --- a/README.md +++ b/README.md @@ -100,4 +100,4 @@ make proto-lint | 2024/01/12 | [Informal Systems](https://informal.systems/) | [eccdd...bcb9d](https://github.com/evstack/ev-node/commit/eccdd0f1793a5ac532011ef4d896de9e0d8bcb9d) | [informal-systems.pdf](docs/audit/informal-systems.pdf) | | 2024/01/10 | [Binary Builders](https://binary.builders/) | [eccdd...bcb9d](https://github.com/evstack/ev-node/commit/eccdd0f1793a5ac532011ef4d896de9e0d8bcb9d) | [binary-builders.pdf](docs/audit/binary-builders.pdf) | -[docs]: +[docs]: diff --git a/RELEASE.md b/RELEASE.md index 8425460343..481a8bff00 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -4,7 +4,7 @@ This document outlines the release process for all Go packages in the ev-node re ## Package Dependency Graph -```ascii +```txt ┌──────────┐ │ core │ (zero dependencies) └────┬─────┘ diff --git a/apps/evm/based/README.md b/apps/evm/based/README.md index 93e00c9f42..18a1c8c31f 100644 --- a/apps/evm/based/README.md +++ b/apps/evm/based/README.md @@ -1,6 +1,6 @@ -# Rollkit EVM Based Sequencer +# Evolve EVM Based Sequencer -This directory contains the implementation of a based EVM sequencer using Rollkit. +This directory contains the implementation of a based EVM sequencer using Evolve. ## Prerequisites @@ -12,7 +12,7 @@ This directory contains the implementation of a based EVM sequencer using Rollki 1. Both EVM and DA layers must be running before starting the aggregator 1. For the EVM layer, Reth can be conveniently run using `docker compose` from the go-execution-evm repository. - 2. For the DA layer, local-da can be built and run from the `rollkit/da/cmd/local-da` directory. + 2. For the DA layer, local-da can be built and run from the `ev-node/da/cmd/local-da` directory. 2. Build the sequencer: diff --git a/apps/evm/based/cmd/init.go b/apps/evm/based/cmd/init.go index 705ae8012c..79b5f3d4d6 100644 --- a/apps/evm/based/cmd/init.go +++ b/apps/evm/based/cmd/init.go @@ -11,11 +11,11 @@ import ( rollgenesis "github.com/evstack/ev-node/pkg/genesis" ) -// InitCmd initializes a new rollkit.yaml file in the current directory +// InitCmd initializes a new evolve.yaml file in the current directory func InitCmd() *cobra.Command { initCmd := &cobra.Command{ Use: "init", - Short: "Initialize rollkit config", + Short: "Initialize evolve config", Long: fmt.Sprintf("This command initializes a new %s file in the specified directory (or current directory if not specified).", rollconf.ConfigName), RunE: func(cmd *cobra.Command, args []string) error { homePath, err := cmd.Flags().GetString(rollconf.FlagRootDir) @@ -47,7 +47,7 @@ func InitCmd() *cobra.Command { } if err := cfg.SaveAsYaml(); err != nil { - return fmt.Errorf("error writing rollkit.yaml file: %w", err) + return fmt.Errorf("error writing evolve.yaml file: %w", err) } if err := rollcmd.LoadOrGenNodeKey(homePath); err != nil { @@ -57,7 +57,7 @@ func InitCmd() *cobra.Command { // get chain ID or use default chainID, _ := cmd.Flags().GetString(rollconf.FlagChainID) if chainID == "" { - chainID = "rollkit-test" + chainID = "evolve-test" } // Initialize genesis without app state diff --git a/apps/evm/based/cmd/run.go b/apps/evm/based/cmd/run.go index a515fc9cb7..91bf756e0f 100644 --- a/apps/evm/based/cmd/run.go +++ b/apps/evm/based/cmd/run.go @@ -41,7 +41,7 @@ func NewExtendedRunNodeCmd(ctx context.Context) *cobra.Command { cmd := &cobra.Command{ Use: "start", - Short: "Run the rollkit node in based mode", + Short: "Run the evolve node in based mode", PreRunE: func(cmd *cobra.Command, args []string) error { var err error diff --git a/apps/evm/based/main.go b/apps/evm/based/main.go index 1b852d8a67..e4aa616893 100644 --- a/apps/evm/based/main.go +++ b/apps/evm/based/main.go @@ -16,7 +16,7 @@ const ( var RootCmd = &cobra.Command{ Use: AppName, - Short: "evm-based is a based evm execution environment for rollkit, out of the box it works with reth", + Short: "evm-based is a based evm execution environment for ev-node, out of the box it works with reth", } func main() { diff --git a/apps/evm/single/README.md b/apps/evm/single/README.md index aae8984e32..ef62a1abc1 100644 --- a/apps/evm/single/README.md +++ b/apps/evm/single/README.md @@ -1,6 +1,6 @@ -# Rollkit EVM Single Sequencer +# Evolve EVM Single Sequencer -This directory contains the implementation of a single EVM sequencer using Rollkit. +This directory contains the implementation of a single EVM sequencer using Ev-node. ## Prerequisites @@ -11,7 +11,7 @@ This directory contains the implementation of a single EVM sequencer using Rollk 1. Both EVM and DA layers must be running before starting the sequencer 1. For the EVM layer, Reth can be conveniently run using `docker compose` from /execution/evm/docker. - 2. For the DA layer, local-da can be built and run from the `rollkit/da/cmd/local-da` directory. + 2. For the DA layer, local-da can be built and run from the `ev-node/da/cmd/local-da` directory. 2. Build the sequencer: diff --git a/apps/evm/single/cmd/init.go b/apps/evm/single/cmd/init.go index 705ae8012c..79b5f3d4d6 100644 --- a/apps/evm/single/cmd/init.go +++ b/apps/evm/single/cmd/init.go @@ -11,11 +11,11 @@ import ( rollgenesis "github.com/evstack/ev-node/pkg/genesis" ) -// InitCmd initializes a new rollkit.yaml file in the current directory +// InitCmd initializes a new evolve.yaml file in the current directory func InitCmd() *cobra.Command { initCmd := &cobra.Command{ Use: "init", - Short: "Initialize rollkit config", + Short: "Initialize evolve config", Long: fmt.Sprintf("This command initializes a new %s file in the specified directory (or current directory if not specified).", rollconf.ConfigName), RunE: func(cmd *cobra.Command, args []string) error { homePath, err := cmd.Flags().GetString(rollconf.FlagRootDir) @@ -47,7 +47,7 @@ func InitCmd() *cobra.Command { } if err := cfg.SaveAsYaml(); err != nil { - return fmt.Errorf("error writing rollkit.yaml file: %w", err) + return fmt.Errorf("error writing evolve.yaml file: %w", err) } if err := rollcmd.LoadOrGenNodeKey(homePath); err != nil { @@ -57,7 +57,7 @@ func InitCmd() *cobra.Command { // get chain ID or use default chainID, _ := cmd.Flags().GetString(rollconf.FlagChainID) if chainID == "" { - chainID = "rollkit-test" + chainID = "evolve-test" } // Initialize genesis without app state diff --git a/apps/evm/single/cmd/run.go b/apps/evm/single/cmd/run.go index 123c55713b..b1a8d3b611 100644 --- a/apps/evm/single/cmd/run.go +++ b/apps/evm/single/cmd/run.go @@ -25,7 +25,7 @@ import ( var RunCmd = &cobra.Command{ Use: "start", Aliases: []string{"node", "run"}, - Short: "Run the rollkit node with EVM execution client", + Short: "Run the evolve node with EVM execution client", RunE: func(cmd *cobra.Command, args []string) error { executor, err := createExecutionClient(cmd) if err != nil { diff --git a/apps/evm/single/main.go b/apps/evm/single/main.go index 984fd62d5b..b959cfea14 100644 --- a/apps/evm/single/main.go +++ b/apps/evm/single/main.go @@ -7,7 +7,7 @@ import ( "github.com/spf13/cobra" rollcmd "github.com/evstack/ev-node/pkg/cmd" - rollkitconfig "github.com/evstack/ev-node/pkg/config" + "github.com/evstack/ev-node/pkg/config" "github.com/evstack/ev-node/apps/evm/single/cmd" ) @@ -16,10 +16,10 @@ func main() { // Initiate the root command rootCmd := &cobra.Command{ Use: "evm-single", - Short: "Rollkit with EVM; single sequencer", + Short: "Evolve with EVM; single sequencer", } - rollkitconfig.AddGlobalFlags(rootCmd, "evm-single") + config.AddGlobalFlags(rootCmd, "evm-single") rootCmd.AddCommand( cmd.InitCmd(), diff --git a/apps/grpc/single/Dockerfile b/apps/grpc/single/Dockerfile index 54dd5f5bb8..ae144860a2 100644 --- a/apps/grpc/single/Dockerfile +++ b/apps/grpc/single/Dockerfile @@ -5,7 +5,7 @@ FROM golang:1.24-alpine AS builder RUN apk add --no-cache git make gcc musl-dev linux-headers # Set working directory -WORKDIR /rollkit +WORKDIR /ev-node # Copy go mod files COPY go.mod go.sum ./ @@ -22,7 +22,7 @@ RUN go mod download COPY . . # Build the application -WORKDIR /rollkit/apps/grpc/single +WORKDIR /ev-node/apps/grpc/single RUN go build -o grpc-single . # Runtime stage @@ -32,21 +32,21 @@ FROM alpine:3.19 RUN apk add --no-cache ca-certificates # Create non-root user -RUN addgroup -g 1000 rollkit && \ - adduser -u 1000 -G rollkit -s /bin/sh -D rollkit +RUN addgroup -g 1000 ev-node && \ + adduser -u 1000 -G ev-node -s /bin/sh -D ev-node # Set working directory -WORKDIR /home/rollkit +WORKDIR /home/ev-node # Copy binary from builder -COPY --from=builder /rollkit/apps/grpc/single/grpc-single /usr/local/bin/ +COPY --from=builder /ev-node/apps/grpc/single/grpc-single /usr/local/bin/ # Create necessary directories -RUN mkdir -p /home/rollkit/.grpc-single && \ - chown -R rollkit:rollkit /home/rollkit +RUN mkdir -p /home/ev-node/.grpc-single && \ + chown -R ev-node:ev-node /home/ev-node # Switch to non-root user -USER rollkit +USER ev-node # Expose ports # P2P port diff --git a/apps/grpc/single/README.md b/apps/grpc/single/README.md index bb6f7fcc38..df1164124b 100644 --- a/apps/grpc/single/README.md +++ b/apps/grpc/single/README.md @@ -1,19 +1,19 @@ # gRPC Single Sequencer App -This application runs a Rollkit node with a single sequencer that connects to a remote execution client via gRPC. It allows you to use any execution layer that implements the Rollkit execution gRPC interface. +This application runs a Evolve node with a single sequencer that connects to a remote execution client via gRPC. It allows you to use any execution layer that implements the Evolve execution gRPC interface. ## Overview The gRPC single sequencer app provides: -- A Rollkit consensus node with single sequencer +- A Evolve consensus node with single sequencer - Connection to remote execution clients via gRPC - Full data availability layer integration - P2P networking capabilities ## Prerequisites -1. A running execution client that implements the Rollkit gRPC execution interface +1. A running execution client that implements the Evolve gRPC execution interface 2. Access to a data availability layer (e.g., local DA, Celestia) 3. Go 1.22 or higher @@ -44,11 +44,11 @@ Edit the configuration file at `~/.grpc-single/config/config.toml` to set your p ### 3. Start the Execution Service -Before starting the Rollkit node, ensure your gRPC execution service is running. +Before starting the Evolve node, ensure your gRPC execution service is running. ### 4. Run the Node -Start the Rollkit node with: +Start the Evolve node with: ```bash ./grpc-single start \ @@ -65,7 +65,7 @@ Start the Rollkit node with: - `--grpc-executor-url`: URL of the gRPC execution service (default: `http://localhost:50051`) -### Common Rollkit Flags +### Common Evolve Flags - `--root-dir`: Root directory for config and data (default: `~/.grpc-single`) - `--chain-id`: The chain ID for your rollup @@ -105,7 +105,7 @@ Start the Rollkit node with: ```text ┌─────────────────┐ ┌──────────────────┐ ┌─────────────┐ -│ Rollkit Node │────▶│ gRPC Execution │────▶│ Execution │ +│ Evolve Node │────▶│ gRPC Execution │────▶│ Execution │ │ (Single Seqr) │◀────│ Client │◀────│ Service │ └─────────────────┘ └──────────────────┘ └─────────────┘ │ │ @@ -151,6 +151,6 @@ If you have issues connecting to the DA layer: ## See Also -- [Rollkit Documentation](https://rollkit.dev) +- [Evolve Documentation](https://ev.xyz) - [gRPC Execution Interface](../../../execution/grpc/README.md) - [Single Sequencer Documentation](../../../sequencers/single/README.md) diff --git a/apps/grpc/single/cmd/init.go b/apps/grpc/single/cmd/init.go index eca4c4a239..e811ee1c26 100644 --- a/apps/grpc/single/cmd/init.go +++ b/apps/grpc/single/cmd/init.go @@ -15,8 +15,8 @@ import ( func InitCmd() *cobra.Command { initCmd := &cobra.Command{ Use: "init", - Short: "Initialize rollkit configuration files", - Long: `Initialize configuration files for a Rollkit node with gRPC execution client. + Short: "Initialize evolve configuration files", + Long: `Initialize configuration files for a Evolve node with gRPC execution client. This will create the necessary configuration structure in the specified root directory.`, Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { @@ -49,7 +49,7 @@ This will create the necessary configuration structure in the specified root dir } if err := cfg.SaveAsYaml(); err != nil { - return fmt.Errorf("error writing rollkit.yaml file: %w", err) + return fmt.Errorf("error writing evolve.yaml file: %w", err) } if err := rollcmd.LoadOrGenNodeKey(homePath); err != nil { diff --git a/apps/grpc/single/cmd/run.go b/apps/grpc/single/cmd/run.go index a0bc401662..fd3eb255a0 100644 --- a/apps/grpc/single/cmd/run.go +++ b/apps/grpc/single/cmd/run.go @@ -26,9 +26,9 @@ const ( var RunCmd = &cobra.Command{ Use: "start", Aliases: []string{"node", "run"}, - Short: "Run the rollkit node with gRPC execution client", - Long: `Start a Rollkit node that connects to a remote execution client via gRPC. -The execution client must implement the Rollkit execution gRPC interface.`, + Short: "Run the evolve node with gRPC execution client", + Long: `Start a Evolve node that connects to a remote execution client via gRPC. +The execution client must implement the Evolve execution gRPC interface.`, RunE: func(cmd *cobra.Command, args []string) error { // Create gRPC execution client executor, err := createGRPCExecutionClient(cmd) @@ -95,7 +95,7 @@ The execution client must implement the Rollkit execution gRPC interface.`, } func init() { - // Add rollkit configuration flags + // Add evolve configuration flags config.AddFlags(RunCmd) // Add gRPC-specific flags diff --git a/apps/grpc/single/docker-compose.yml b/apps/grpc/single/docker-compose.yml index c4b86da4e9..01b2326189 100644 --- a/apps/grpc/single/docker-compose.yml +++ b/apps/grpc/single/docker-compose.yml @@ -29,8 +29,8 @@ services: # timeout: 3s # retries: 5 - # Rollkit node with gRPC execution client - rollkit-grpc: + # Evolve node with gRPC execution client + evolve-grpc: build: context: ../../../ dockerfile: apps/grpc/single/Dockerfile @@ -49,10 +49,10 @@ services: - DA_NAMESPACE=00000000000000000000000000000000000000000000000000deadbeef - GRPC_EXECUTOR_URL=http://host.docker.internal:50051 # Change to your execution service volumes: - - rollkit-data:/home/rollkit/.grpc-single + - evolve-data:/home/evolve/.grpc-single command: - start - - --root-dir=/home/rollkit/.grpc-single + - --root-dir=/home/evolve/.grpc-single - --chain-id=${CHAIN_ID:-grpc-test-chain} - --da.address=${DA_ADDRESS:-http://local-da:7980} - --da.namespace=${DA_NAMESPACE} @@ -63,4 +63,4 @@ services: - --instrumentation.prometheus-listen-addr=0.0.0.0:26660 volumes: - rollkit-data: + evolve-data: diff --git a/apps/grpc/single/main.go b/apps/grpc/single/main.go index f32d7a9c1a..a0d7f934d0 100644 --- a/apps/grpc/single/main.go +++ b/apps/grpc/single/main.go @@ -6,8 +6,8 @@ import ( "github.com/spf13/cobra" - rollcmd "github.com/evstack/ev-node/pkg/cmd" - rollkitconfig "github.com/evstack/ev-node/pkg/config" + evcmd "github.com/evstack/ev-node/pkg/cmd" + "github.com/evstack/ev-node/pkg/config" "github.com/evstack/ev-node/apps/grpc/single/cmd" ) @@ -16,21 +16,21 @@ func main() { // Initiate the root command rootCmd := &cobra.Command{ Use: "grpc-single", - Short: "Rollkit with gRPC execution client; single sequencer", - Long: `Run a Rollkit node with a gRPC-based execution client. + Short: "Evolve node with gRPC execution client; single sequencer", + Long: `Run a Evolve node with a gRPC-based execution client. This allows you to connect to any execution layer that implements -the Rollkit execution gRPC interface.`, +the Evolve execution gRPC interface.`, } - rollkitconfig.AddGlobalFlags(rootCmd, "grpc-single") + config.AddGlobalFlags(rootCmd, "grpc-single") rootCmd.AddCommand( cmd.InitCmd(), cmd.RunCmd, - rollcmd.VersionCmd, - rollcmd.NetInfoCmd, - rollcmd.StoreUnsafeCleanCmd, - rollcmd.KeysCmd(), + evcmd.VersionCmd, + evcmd.NetInfoCmd, + evcmd.StoreUnsafeCleanCmd, + evcmd.KeysCmd(), ) if err := rootCmd.Execute(); err != nil { diff --git a/apps/testapp/cmd/init.go b/apps/testapp/cmd/init.go index 705ae8012c..79b5f3d4d6 100644 --- a/apps/testapp/cmd/init.go +++ b/apps/testapp/cmd/init.go @@ -11,11 +11,11 @@ import ( rollgenesis "github.com/evstack/ev-node/pkg/genesis" ) -// InitCmd initializes a new rollkit.yaml file in the current directory +// InitCmd initializes a new evolve.yaml file in the current directory func InitCmd() *cobra.Command { initCmd := &cobra.Command{ Use: "init", - Short: "Initialize rollkit config", + Short: "Initialize evolve config", Long: fmt.Sprintf("This command initializes a new %s file in the specified directory (or current directory if not specified).", rollconf.ConfigName), RunE: func(cmd *cobra.Command, args []string) error { homePath, err := cmd.Flags().GetString(rollconf.FlagRootDir) @@ -47,7 +47,7 @@ func InitCmd() *cobra.Command { } if err := cfg.SaveAsYaml(); err != nil { - return fmt.Errorf("error writing rollkit.yaml file: %w", err) + return fmt.Errorf("error writing evolve.yaml file: %w", err) } if err := rollcmd.LoadOrGenNodeKey(homePath); err != nil { @@ -57,7 +57,7 @@ func InitCmd() *cobra.Command { // get chain ID or use default chainID, _ := cmd.Flags().GetString(rollconf.FlagChainID) if chainID == "" { - chainID = "rollkit-test" + chainID = "evolve-test" } // Initialize genesis without app state diff --git a/apps/testapp/cmd/init_test.go b/apps/testapp/cmd/init_test.go index 7e7d39f768..1a5e31aac2 100644 --- a/apps/testapp/cmd/init_test.go +++ b/apps/testapp/cmd/init_test.go @@ -26,7 +26,7 @@ func TestInitCommand(t *testing.T) { // Change to the temporary directory require.NoError(t, os.Chdir(dir)) - // Remove any existing rollkit.yaml files in the test directory + // Remove any existing evolve.yaml files in the test directory configPath := filepath.Join(dir, "config", rollconf.ConfigName) _ = os.Remove(configPath) // Ignore error if file doesn't exist diff --git a/apps/testapp/cmd/root.go b/apps/testapp/cmd/root.go index 183a8e6d13..d7001557f6 100644 --- a/apps/testapp/cmd/root.go +++ b/apps/testapp/cmd/root.go @@ -3,7 +3,7 @@ package cmd import ( "github.com/spf13/cobra" - rollkitconfig "github.com/evstack/ev-node/pkg/config" + config "github.com/evstack/ev-node/pkg/config" ) const ( @@ -16,14 +16,14 @@ const ( ) func init() { - rollkitconfig.AddGlobalFlags(RootCmd, AppName) - rollkitconfig.AddFlags(RunCmd) + config.AddGlobalFlags(RootCmd, AppName) + config.AddFlags(RunCmd) // Add the KV endpoint flag specifically to the RunCmd RunCmd.Flags().String(flagKVEndpoint, "", "Address and port for the KV executor HTTP server") } -// RootCmd is the root command for Rollkit +// RootCmd is the root command for Evolve var RootCmd = &cobra.Command{ Use: AppName, - Short: "Testapp is a test application for Rollkit, it consists of a simple key-value store and a single sequencer.", + Short: "Testapp is a test application for Evolve, it consists of a simple key-value store and a single sequencer.", } diff --git a/apps/testapp/kv/README.md b/apps/testapp/kv/README.md index 03cc0a88dc..e080067ac9 100644 --- a/apps/testapp/kv/README.md +++ b/apps/testapp/kv/README.md @@ -1,10 +1,10 @@ # KV Executor -This is a simple key-value store executor implementation for testing Rollkit nodes. +This is a simple key-value store executor implementation for testing Evolve nodes. ## Server Lifecycle -The HTTP server starts when the Rollkit node starts and is automatically shut down when the node stops (including when receiving CTRL+C or other termination signals). The server is context-aware, meaning: +The HTTP server starts when the Evolve node starts and is automatically shut down when the node stops (including when receiving CTRL+C or other termination signals). The server is context-aware, meaning: 1. It gracefully handles in-progress requests during shutdown 2. It automatically shuts down when the node's context is cancelled diff --git a/block/da_includer.go b/block/da_includer.go index 5af2f07116..3ea8cf6f80 100644 --- a/block/da_includer.go +++ b/block/da_includer.go @@ -30,8 +30,8 @@ func (m *Manager) DAIncluderLoop(ctx context.Context, errCh chan<- error) { } if daIncluded { m.logger.Debug().Uint64("height", nextHeight).Msg("both header and data are DA-included, advancing height") - if err := m.SetRollkitHeightToDAHeight(ctx, nextHeight); err != nil { - errCh <- fmt.Errorf("failed to set rollkit height to DA height: %w", err) + if err := m.SetSequencerHeightToDAHeight(ctx, nextHeight); err != nil { + errCh <- fmt.Errorf("failed to set sequencer height to DA height: %w", err) return } // Both header and data are DA-included, so we can advance the height diff --git a/block/da_includer_test.go b/block/da_includer_test.go index bb93b3fb49..16019c4100 100644 --- a/block/da_includer_test.go +++ b/block/da_includer_test.go @@ -61,10 +61,10 @@ func TestDAIncluderLoop_AdvancesHeightWhenBothDAIncluded(t *testing.T) { // Mock expectations for SetRollkitHeightToDAHeight method headerHeightBytes := make([]byte, 8) binary.LittleEndian.PutUint64(headerHeightBytes, uint64(1)) - store.On("SetMetadata", mock.Anything, fmt.Sprintf("%s/%d/h", storepkg.RollkitHeightToDAHeightKey, uint64(5)), headerHeightBytes).Return(nil).Once() + store.On("SetMetadata", mock.Anything, fmt.Sprintf("%s/%d/h", storepkg.HeightToDAHeightKey, uint64(5)), headerHeightBytes).Return(nil).Once() dataHeightBytes := make([]byte, 8) binary.LittleEndian.PutUint64(dataHeightBytes, uint64(1)) - store.On("SetMetadata", mock.Anything, fmt.Sprintf("%s/%d/d", storepkg.RollkitHeightToDAHeightKey, uint64(5)), dataHeightBytes).Return(nil).Once() + store.On("SetMetadata", mock.Anything, fmt.Sprintf("%s/%d/d", storepkg.HeightToDAHeightKey, uint64(5)), dataHeightBytes).Return(nil).Once() // Mock expectations for incrementDAIncludedHeight method heightBytes := make([]byte, 8) binary.LittleEndian.PutUint64(heightBytes, expectedDAIncludedHeight) @@ -275,10 +275,10 @@ func TestDAIncluderLoop_MultipleConsecutiveHeightsDAIncluded(t *testing.T) { height := startDAIncludedHeight + uint64(i+1) headerHeightBytes := make([]byte, 8) binary.LittleEndian.PutUint64(headerHeightBytes, uint64(i+1)) - store.On("SetMetadata", mock.Anything, fmt.Sprintf("%s/%d/h", storepkg.RollkitHeightToDAHeightKey, height), headerHeightBytes).Return(nil).Once() + store.On("SetMetadata", mock.Anything, fmt.Sprintf("%s/%d/h", storepkg.HeightToDAHeightKey, height), headerHeightBytes).Return(nil).Once() dataHeightBytes := make([]byte, 8) binary.LittleEndian.PutUint64(dataHeightBytes, uint64(i+1)) - store.On("SetMetadata", mock.Anything, fmt.Sprintf("%s/%d/d", storepkg.RollkitHeightToDAHeightKey, height), dataHeightBytes).Return(nil).Once() + store.On("SetMetadata", mock.Anything, fmt.Sprintf("%s/%d/d", storepkg.HeightToDAHeightKey, height), dataHeightBytes).Return(nil).Once() } store.On("SetMetadata", mock.Anything, storepkg.DAIncludedHeightKey, mock.Anything).Return(nil).Times(numConsecutive) exec.On("SetFinal", mock.Anything, mock.Anything).Return(nil).Times(numConsecutive) @@ -322,7 +322,7 @@ func TestDAIncluderLoop_AdvancesHeightWhenDataHashIsEmptyAndHeaderDAIncluded(t * // Mock expectations for SetRollkitHeightToDAHeight method headerHeightBytes := make([]byte, 8) binary.LittleEndian.PutUint64(headerHeightBytes, uint64(1)) - store.On("SetMetadata", mock.Anything, fmt.Sprintf("%s/%d/h", storepkg.RollkitHeightToDAHeightKey, uint64(5)), headerHeightBytes).Return(nil).Once() + store.On("SetMetadata", mock.Anything, fmt.Sprintf("%s/%d/h", storepkg.HeightToDAHeightKey, uint64(5)), headerHeightBytes).Return(nil).Once() // Note: For empty data, data SetMetadata call should still be made but data won't be marked as DA-included in cache, // so SetRollkitHeightToDAHeight will fail when trying to get the DA height for data // Actually, let's check if this case is handled differently for empty txs @@ -331,7 +331,7 @@ func TestDAIncluderLoop_AdvancesHeightWhenDataHashIsEmptyAndHeaderDAIncluded(t * m.dataCache.SetDAIncluded(dataHash, uint64(1)) dataHeightBytes := make([]byte, 8) binary.LittleEndian.PutUint64(dataHeightBytes, uint64(1)) - store.On("SetMetadata", mock.Anything, fmt.Sprintf("%s/%d/d", storepkg.RollkitHeightToDAHeightKey, uint64(5)), dataHeightBytes).Return(nil).Once() + store.On("SetMetadata", mock.Anything, fmt.Sprintf("%s/%d/d", storepkg.HeightToDAHeightKey, uint64(5)), dataHeightBytes).Return(nil).Once() // Mock expectations for incrementDAIncludedHeight method heightBytes := make([]byte, 8) binary.LittleEndian.PutUint64(heightBytes, expectedDAIncludedHeight) diff --git a/block/manager.go b/block/manager.go index 070900b691..3e145ec480 100644 --- a/block/manager.go +++ b/block/manager.go @@ -43,7 +43,7 @@ const ( // defaultMempoolTTL is the number of blocks until transaction is dropped from mempool defaultMempoolTTL = 25 - // maxSubmitAttempts defines how many times Rollkit will re-try to publish block to DA layer. + // maxSubmitAttempts defines how many times evolve will re-try to publish block to DA layer. // This is temporary solution. It will be removed in future versions. maxSubmitAttempts = 30 @@ -144,7 +144,7 @@ type Manager struct { exec coreexecutor.Executor - // daIncludedHeight is rollkit height at which all blocks have been included + // daIncludedHeight is evolve height at which all blocks have been included // in the DA daIncludedHeight atomic.Uint64 da coreda.DA @@ -495,14 +495,14 @@ func (m *Manager) IsDAIncluded(ctx context.Context, height uint64) (bool, error) return isIncluded, nil } -// SetRollkitHeightToDAHeight stores the mapping from a Rollkit block height to the corresponding +// SetSequencerHeightToDAHeight stores the mapping from a Evolve block height to the corresponding // DA (Data Availability) layer heights where the block's header and data were included. // This mapping is persisted in the store metadata and is used to track which DA heights -// contain the block components for a given Rollkit height. +// contain the block components for a given Evolve height. // // For blocks with empty transactions, both header and data use the same DA height since // empty transaction data is not actually published to the DA layer. -func (m *Manager) SetRollkitHeightToDAHeight(ctx context.Context, height uint64) error { +func (m *Manager) SetSequencerHeightToDAHeight(ctx context.Context, height uint64) error { header, data, err := m.store.GetBlockData(ctx, height) if err != nil { return err @@ -514,7 +514,7 @@ func (m *Manager) SetRollkitHeightToDAHeight(ctx context.Context, height uint64) return fmt.Errorf("header hash %s not found in cache", headerHash) } binary.LittleEndian.PutUint64(headerHeightBytes, daHeightForHeader) - if err := m.store.SetMetadata(ctx, fmt.Sprintf("%s/%d/h", storepkg.RollkitHeightToDAHeightKey, height), headerHeightBytes); err != nil { + if err := m.store.SetMetadata(ctx, fmt.Sprintf("%s/%d/h", storepkg.HeightToDAHeightKey, height), headerHeightBytes); err != nil { return err } dataHeightBytes := make([]byte, 8) @@ -528,7 +528,7 @@ func (m *Manager) SetRollkitHeightToDAHeight(ctx context.Context, height uint64) } binary.LittleEndian.PutUint64(dataHeightBytes, daHeightForData) } - if err := m.store.SetMetadata(ctx, fmt.Sprintf("%s/%d/d", storepkg.RollkitHeightToDAHeightKey, height), dataHeightBytes); err != nil { + if err := m.store.SetMetadata(ctx, fmt.Sprintf("%s/%d/d", storepkg.HeightToDAHeightKey, height), dataHeightBytes); err != nil { return err } return nil diff --git a/block/manager_test.go b/block/manager_test.go index 5abacc9ce8..97c2e22da5 100644 --- a/block/manager_test.go +++ b/block/manager_test.go @@ -1089,13 +1089,13 @@ func TestSetRollkitHeightToDAHeight(t *testing.T) { m.dataCache.SetDAIncluded(data.DACommitment().String(), dataHeight) // Mock metadata storage - headerKey := fmt.Sprintf("%s/%d/h", storepkg.RollkitHeightToDAHeightKey, height) - dataKey := fmt.Sprintf("%s/%d/d", storepkg.RollkitHeightToDAHeightKey, height) + headerKey := fmt.Sprintf("%s/%d/h", storepkg.HeightToDAHeightKey, height) + dataKey := fmt.Sprintf("%s/%d/d", storepkg.HeightToDAHeightKey, height) mockStore.On("SetMetadata", mock.Anything, headerKey, mock.Anything).Return(nil) mockStore.On("SetMetadata", mock.Anything, dataKey, mock.Anything).Return(nil) // Call the method - err := m.SetRollkitHeightToDAHeight(ctx, height) + err := m.SetSequencerHeightToDAHeight(ctx, height) require.NoError(err) mockStore.AssertExpectations(t) @@ -1119,13 +1119,13 @@ func TestSetRollkitHeightToDAHeight(t *testing.T) { // Note: we don't set data in cache for empty transactions // Mock metadata storage - both should use header height for empty transactions - headerKey := fmt.Sprintf("%s/%d/h", storepkg.RollkitHeightToDAHeightKey, height) - dataKey := fmt.Sprintf("%s/%d/d", storepkg.RollkitHeightToDAHeightKey, height) + headerKey := fmt.Sprintf("%s/%d/h", storepkg.HeightToDAHeightKey, height) + dataKey := fmt.Sprintf("%s/%d/d", storepkg.HeightToDAHeightKey, height) mockStore.On("SetMetadata", mock.Anything, headerKey, mock.Anything).Return(nil) mockStore.On("SetMetadata", mock.Anything, dataKey, mock.Anything).Return(nil) // Call the method - err := m.SetRollkitHeightToDAHeight(ctx, height) + err := m.SetSequencerHeightToDAHeight(ctx, height) require.NoError(err) mockStore.AssertExpectations(t) @@ -1147,7 +1147,7 @@ func TestSetRollkitHeightToDAHeight(t *testing.T) { m.dataCache.SetDAIncluded(data.DACommitment().String(), uint64(11)) // Call the method - should fail - err := m.SetRollkitHeightToDAHeight(ctx, height) + err := m.SetSequencerHeightToDAHeight(ctx, height) require.Error(err) require.Contains(err.Error(), "header hash") require.Contains(err.Error(), "not found in cache") @@ -1171,11 +1171,11 @@ func TestSetRollkitHeightToDAHeight(t *testing.T) { m.headerCache.SetDAIncluded(header.Hash().String(), uint64(10)) // Mock metadata storage for header (should succeed) - headerKey := fmt.Sprintf("%s/%d/h", storepkg.RollkitHeightToDAHeightKey, height) + headerKey := fmt.Sprintf("%s/%d/h", storepkg.HeightToDAHeightKey, height) mockStore.On("SetMetadata", mock.Anything, headerKey, mock.Anything).Return(nil) // Call the method - should fail on data lookup - err := m.SetRollkitHeightToDAHeight(ctx, height) + err := m.SetSequencerHeightToDAHeight(ctx, height) require.Error(err) require.Contains(err.Error(), "data hash") require.Contains(err.Error(), "not found in cache") @@ -1194,7 +1194,7 @@ func TestSetRollkitHeightToDAHeight(t *testing.T) { mockStore.On("GetBlockData", mock.Anything, height).Return(nil, nil, errors.New("block not found")) // Call the method - should fail - err := m.SetRollkitHeightToDAHeight(ctx, height) + err := m.SetSequencerHeightToDAHeight(ctx, height) require.Error(err) mockStore.AssertExpectations(t) diff --git a/block/pending_data.go b/block/pending_data.go index 46722ead8a..1301479935 100644 --- a/block/pending_data.go +++ b/block/pending_data.go @@ -22,7 +22,7 @@ const LastSubmittedDataHeightKey = "last-submitted-data-height" // lastSubmittedDataHeight is updated only after receiving confirmation from DA. // Worst case scenario is when data was successfully submitted to DA, but confirmation was not received (e.g. node was // restarted, networking issue occurred). In this case data is re-submitted to DA (it's extra cost). -// rollkit is able to skip duplicate data so this shouldn't affect full nodes. +// evolve is able to skip duplicate data so this shouldn't affect full nodes. // Note: Submission of pending data to DA should account for the DA max blob size. type PendingData struct { base *pendingBase[*types.Data] diff --git a/block/pending_headers.go b/block/pending_headers.go index 6b435f8f29..ecdb200ea5 100644 --- a/block/pending_headers.go +++ b/block/pending_headers.go @@ -19,7 +19,7 @@ import ( // lastSubmittedHeaderHeight is updated only after receiving confirmation from DA. // Worst case scenario is when headers was successfully submitted to DA, but confirmation was not received (e.g. node was // restarted, networking issue occurred). In this case headers are re-submitted to DA (it's extra cost). -// rollkit is able to skip duplicate headers so this shouldn't affect full nodes. +// evolve is able to skip duplicate headers so this shouldn't affect full nodes. // TODO(tzdybal): we shouldn't try to push all pending headers at once; this should depend on max blob size type PendingHeaders struct { base *pendingBase[*types.SignedHeader] diff --git a/block/publish_block_p2p_test.go b/block/publish_block_p2p_test.go index 06de5162b8..df0fc32591 100644 --- a/block/publish_block_p2p_test.go +++ b/block/publish_block_p2p_test.go @@ -27,7 +27,7 @@ import ( "github.com/evstack/ev-node/pkg/signer" "github.com/evstack/ev-node/pkg/signer/noop" "github.com/evstack/ev-node/pkg/store" - rollkitSync "github.com/evstack/ev-node/pkg/sync" + evSync "github.com/evstack/ev-node/pkg/sync" "github.com/evstack/ev-node/types" ) @@ -160,7 +160,7 @@ func (b broadcasterFn[T]) WriteToStoreAndBroadcast(ctx context.Context, payload return b(ctx, payload) } -func setupBlockManager(t *testing.T, ctx context.Context, workDir string, mainKV ds.Batching, blockTime time.Duration, signer signer.Signer) (*Manager, *rollkitSync.HeaderSyncService, *rollkitSync.DataSyncService) { +func setupBlockManager(t *testing.T, ctx context.Context, workDir string, mainKV ds.Batching, blockTime time.Duration, signer signer.Signer) (*Manager, *evSync.HeaderSyncService, *evSync.DataSyncService) { t.Helper() nodeConfig := config.DefaultConfig nodeConfig.Node.BlockTime = config.DurationWrapper{Duration: blockTime} @@ -185,18 +185,18 @@ func setupBlockManager(t *testing.T, ctx context.Context, workDir string, mainKV err = p2pClient.Start(ctx) require.NoError(t, err) - const RollkitPrefix = "0" - ktds.Wrap(mainKV, ktds.PrefixTransform{Prefix: ds.NewKey(RollkitPrefix)}) + const evPrefix = "0" + ktds.Wrap(mainKV, ktds.PrefixTransform{Prefix: ds.NewKey(evPrefix)}) // Get subsystem loggers. The With("module", ...) pattern from cosmossdk.io/log // is replaced by getting a named logger from ipfs/go-log. headerSyncLogger := zerolog.Nop() dataSyncLogger := zerolog.Nop() blockManagerLogger := zerolog.Nop() - headerSyncService, err := rollkitSync.NewHeaderSyncService(mainKV, nodeConfig, genesisDoc, p2pClient, headerSyncLogger) // Pass headerSyncLogger + headerSyncService, err := evSync.NewHeaderSyncService(mainKV, nodeConfig, genesisDoc, p2pClient, headerSyncLogger) // Pass headerSyncLogger require.NoError(t, err) require.NoError(t, headerSyncService.Start(ctx)) - dataSyncService, err := rollkitSync.NewDataSyncService(mainKV, nodeConfig, genesisDoc, p2pClient, dataSyncLogger) + dataSyncService, err := evSync.NewDataSyncService(mainKV, nodeConfig, genesisDoc, p2pClient, dataSyncLogger) require.NoError(t, err) require.NoError(t, dataSyncService.Start(ctx)) diff --git a/client/README.md b/client/README.md index 02467628b1..3fd9722e3a 100644 --- a/client/README.md +++ b/client/README.md @@ -1,10 +1,10 @@ -# Rollkit Client Libraries +# Evolve Client Libraries -This directory contains client libraries for interacting with Rollkit nodes in various programming languages. +This directory contains client libraries for interacting with Evolve nodes in various programming languages. ## Structure -```ascii +```txt client/ ├── crates/ # Rust client libraries │ ├── types/ # Generated protobuf types for Rust diff --git a/client/crates/client/README.md b/client/crates/client/README.md index 3c126eafef..76b1e07769 100644 --- a/client/crates/client/README.md +++ b/client/crates/client/README.md @@ -36,7 +36,7 @@ use ev_client::{Client, HealthClient}; #[tokio::main] async fn main() -> Result<(), Box> { - // Connect to a Rollkit node + // Connect to a evolve node let client = Client::connect("http://localhost:50051").await?; // Check health @@ -70,17 +70,17 @@ use ev_client::{Client, ClientTlsConfig}; // Enable TLS with default configuration let client = Client::builder() - .endpoint("https://secure-node.rollkit.dev") + .endpoint("https://secure-node.ev.xyz") .tls() .build() .await?; // Or with custom TLS configuration let tls_config = ClientTlsConfig::new() - .domain_name("secure-node.rollkit.dev"); + .domain_name("secure-node.ev.xyz"); let client = Client::builder() - .endpoint("https://secure-node.rollkit.dev") + .endpoint("https://secure-node.ev.xyz") .tls_config(tls_config) .build() .await?; @@ -106,7 +106,7 @@ let client = Client::connect_with_config( ## Services -The client provides wrappers for all Rollkit gRPC services. All service methods are now thread-safe and can be called concurrently: +The client provides wrappers for all evolve gRPC services. All service methods are now thread-safe and can be called concurrently: ### Health Service diff --git a/client/crates/client/examples/basic.rs b/client/crates/client/examples/basic.rs index 9eb1cc0555..8a9cbd6ab7 100644 --- a/client/crates/client/examples/basic.rs +++ b/client/crates/client/examples/basic.rs @@ -6,13 +6,13 @@ async fn main() -> Result<(), Box> { // Initialize tracing for better debugging tracing_subscriber::fmt::init(); - // Connect to a Rollkit node + // Connect to a Evolve node let endpoint = - std::env::var("ROLLKIT_ENDPOINT").unwrap_or_else(|_| "http://localhost:50051".to_string()); - println!("Connecting to Rollkit node at: {endpoint}"); + std::env::var("EVOLVE_ENDPOINT").unwrap_or_else(|_| "http://localhost:50051".to_string()); + println!("Connecting to evolve node at: {endpoint}"); let client = Client::connect(&endpoint).await?; - println!("Successfully connected to Rollkit node"); + println!("Successfully connected to evolve node"); // Check health status println!("\n=== Health Check ==="); diff --git a/client/crates/client/src/lib.rs b/client/crates/client/src/lib.rs index 6dedd12e8b..d150dcb96a 100644 --- a/client/crates/client/src/lib.rs +++ b/client/crates/client/src/lib.rs @@ -1,6 +1,6 @@ -//! Rollkit Rust Client Library +//! Evolve Rust Client Library //! -//! This library provides a Rust client for interacting with Rollkit nodes via gRPC. +//! This library provides a Rust client for interacting with Evolve nodes via gRPC. //! //! # Example //! @@ -9,7 +9,7 @@ //! //! #[tokio::main] //! async fn main() -> Result<(), Box> { -//! // Connect to a Rollkit node +//! // Connect to a Evolve node //! let client = Client::connect("http://localhost:50051").await?; //! //! // Check health @@ -51,17 +51,17 @@ //! async fn main() -> Result<(), Box> { //! // Create a client with TLS enabled //! let client = Client::builder() -//! .endpoint("https://secure-node.rollkit.dev") +//! .endpoint("https://secure-node.ev.xyz") //! .tls() // Enable TLS with default configuration //! .build() //! .await?; //! //! // Or with custom TLS configuration //! let tls_config = ClientTlsConfig::new() -//! .domain_name("secure-node.rollkit.dev"); +//! .domain_name("secure-node.ev.xyz"); //! //! let client = Client::builder() -//! .endpoint("https://secure-node.rollkit.dev") +//! .endpoint("https://secure-node.ev.xyz") //! .tls_config(tls_config) //! .build() //! .await?; @@ -85,7 +85,7 @@ pub use p2p::P2PClient; pub use signer::SignerClient; pub use store::StoreClient; -// Re-export types from rollkit-types for convenience +// Re-export types from evolve-types for convenience pub use ev_types::v1; // Re-export tonic transport types for convenience diff --git a/client/scripts/generate-protos.sh b/client/scripts/generate-protos.sh index d306ad6823..f6d13042f1 100755 --- a/client/scripts/generate-protos.sh +++ b/client/scripts/generate-protos.sh @@ -27,13 +27,13 @@ if [ "$CURRENT_VERSION" != "$PROTOC_VERSION" ]; then fi echo "Cleaning existing generated files..." -rm -f "$PROJECT_ROOT/client/crates/rollkit-types/src/proto/"*.rs +rm -f "$PROJECT_ROOT/client/crates/types/src/proto/"*.rs echo "Generating proto files..." -cd "$PROJECT_ROOT/client/crates/rollkit-types" +cd "$PROJECT_ROOT/client/crates/types" cargo build echo "Proto generation complete!" echo "" echo "If you see differences in git, it may be due to protoc version differences." -echo "CI uses protoc version $PROTOC_VERSION" \ No newline at end of file +echo "CI uses protoc version $PROTOC_VERSION" diff --git a/core/README.md b/core/README.md index bcb793dc09..5afbbef6fe 100644 --- a/core/README.md +++ b/core/README.md @@ -1,14 +1,14 @@ -# Rollkit Core Package +# Evolve Core Package -The `core` package is the zero-dependency foundation of Rollkit. It provides the essential interfaces and types that enable modular builds of different application formats (e.g., sequencer, full node, light client) while preventing circular dependencies. +The `core` package is the zero-dependency foundation of Evolve. It provides the essential interfaces and types that enable modular builds of different application formats (e.g., sequencer, full node, light client) while preventing circular dependencies. ## Purpose -The primary goal of the `core` package is to define common contracts (interfaces) for key components within Rollkit, such as execution, sequencing, and data availability (DA). By having all other Rollkit modules depend solely on `core`, we decouple their implementations. This allows each component to be compiled independently and avoids circular import issues, which can arise when components directly depend on each other. +The primary goal of the `core` package is to define common contracts (interfaces) for key components within Evolve, such as execution, sequencing, and data availability (DA). By having all other Evolve modules depend solely on `core`, we decouple their implementations. This allows each component to be compiled independently and avoids circular import issues, which can arise when components directly depend on each other. ## Key Interfaces -The `core` package defines several crucial interfaces that standardize interactions between different parts of a Rollkit node. Here are the main ones: +The `core` package defines several crucial interfaces that standardize interactions between different parts of a Evolve node. Here are the main ones: ### Execution @@ -103,7 +103,7 @@ type Client interface { ## Contributing -The `core` package is central to Rollkit's architecture. Modifications here can have wide-ranging effects. Please adhere to the following guidelines when contributing: +The `core` package is central to Evolve's architecture. Modifications here can have wide-ranging effects. Please adhere to the following guidelines when contributing: - **Compatibility:** Prioritize backward compatibility. Changes to existing interfaces should be made carefully. - **ADRs for Significant Changes:** For substantial changes, especially to interfaces, please propose them via an Architecture Decision Record (ADR). The ADR should detail the proposed changes and the reasoning behind them. diff --git a/core/da/da.go b/core/da/da.go index a3effde2dc..b297fb23ef 100644 --- a/core/da/da.go +++ b/core/da/da.go @@ -76,7 +76,7 @@ type ResultRetrieve struct { // StatusCode is a type for DA layer return status. // TODO: define an enum of different non-happy-path cases -// that might need to be handled by Rollkit independent of +// that might need to be handled by Evolve independent of // the underlying DA chain. type StatusCode uint64 diff --git a/core/execution/execution.go b/core/execution/execution.go index e3388a2e67..f589275373 100644 --- a/core/execution/execution.go +++ b/core/execution/execution.go @@ -5,7 +5,7 @@ import ( "time" ) -// Executor defines the interface that execution clients must implement to be compatible with Rollkit. +// Executor defines the interface that execution clients must implement to be compatible with Evolve. // This interface enables the separation between consensus and execution layers, allowing for modular // and pluggable execution environments. // diff --git a/da/cmd/local-da/main.go b/da/cmd/local-da/main.go index c9db649e2f..5823b77156 100644 --- a/da/cmd/local-da/main.go +++ b/da/cmd/local-da/main.go @@ -37,7 +37,7 @@ func main() { // create logger zerolog.SetGlobalLevel(zerolog.InfoLevel) - logger := zerolog.New(os.Stderr).With().Timestamp().Str("component", "da").Logger() + logger := zerolog.New(zerolog.ConsoleWriter{Out: os.Stderr}).With().Timestamp().Str("component", "da").Logger() // Create LocalDA instance with custom maxBlobSize if provided var opts []func(*LocalDA) *LocalDA diff --git a/docs/.gitignore b/docs/.gitignore deleted file mode 100644 index 7585238efe..0000000000 --- a/docs/.gitignore +++ /dev/null @@ -1 +0,0 @@ -book diff --git a/docs/.vitepress/components/callout.vue b/docs/.vitepress/components/callout.vue new file mode 100644 index 0000000000..75ae3ad8bb --- /dev/null +++ b/docs/.vitepress/components/callout.vue @@ -0,0 +1,15 @@ + + + + + diff --git a/docs/.vitepress/components/keplr.png b/docs/.vitepress/components/keplr.png new file mode 100644 index 0000000000..23bf042e3e Binary files /dev/null and b/docs/.vitepress/components/keplr.png differ diff --git a/docs/.vitepress/components/keplr.vue b/docs/.vitepress/components/keplr.vue new file mode 100644 index 0000000000..374108ed45 --- /dev/null +++ b/docs/.vitepress/components/keplr.vue @@ -0,0 +1,43 @@ + + + \ No newline at end of file diff --git a/docs/.vitepress/components/rosm.json b/docs/.vitepress/components/rosm.json new file mode 100644 index 0000000000..c11e950459 --- /dev/null +++ b/docs/.vitepress/components/rosm.json @@ -0,0 +1,46 @@ +{ + "rpc": "https://rpc.rosm.ev.xyz", + "rest": "https://api.rosm.ev.xyz", + "chainId": "rosm", + "chainName": "Evolve Cosmwasm Testnet", + "stakeCurrency": { + "coinDenom": "ROSM", + "coinMinimalDenom": "urosm", + "coinDecimals": 6 + }, + "bech32Config": { + "bech32PrefixAccAddr": "wasm", + "bech32PrefixAccPub": "wasmpub", + "bech32PrefixValAddr": "wasmvaloper", + "bech32PrefixValPub": "wasmvaloperpub", + "bech32PrefixConsAddr": "wasmvalcons", + "bech32PrefixConsPub": "wasmvalconspub" + }, + "bip44": { + "coinType": 118 + }, + "currencies": [ + { + "coinDenom": "ROSM", + "coinMinimalDenom": "urosm", + "coinDecimals": 6 + } + ], + "feeCurrencies": [ + { + "coinDenom": "ROSM", + "coinMinimalDenom": "urosm", + "coinDecimals": 6 + } + ], + "gasPriceStep": { + "low": 0.05, + "average": 0.125, + "high": 0.2 + }, + "features": [ + "stargate", + "no-legacy-stdTx", + "ibc-transfer" + ] +} diff --git a/docs/.vitepress/components/twitter.vue b/docs/.vitepress/components/twitter.vue new file mode 100644 index 0000000000..a682a73a14 --- /dev/null +++ b/docs/.vitepress/components/twitter.vue @@ -0,0 +1,16 @@ + + + + + + diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts new file mode 100644 index 0000000000..8787c6f13d --- /dev/null +++ b/docs/.vitepress/config.ts @@ -0,0 +1,332 @@ +import { withMermaid } from "vitepress-plugin-mermaid"; +import { useSidebar } from 'vitepress-openapi' +import spec from '../src/openapi-rpc.json' with { type: 'json' } + +const telegramSVG = ` + +`; + +const { BASE: base = "/" } = process.env; + +const sidebar = useSidebar({ + spec, + // Optionally, you can specify a link prefix for all generated sidebar items. Default is `/operations/`. + linkPrefix: '/api/', +}) + +// https://vitepress.dev/reference/site-config +export default withMermaid({ + lang: "en-US", + title: " ", + titleTemplate: false, + description: "Launch Fast. Build Your Own Network.", + lastUpdated: true, + cleanUrls: true, + ignoreDeadLinks: true, + base: base, + sitemap: { + hostname: "https://ev.xyz", + }, + + head: [ + ["link", { rel: "icon", href: "/img/favicon.svg", type: "image/svg+xml" }], + ["link", { rel: "icon", href: "/img/favicon.png", type: "image/png" }], + [ + "link", + { rel: "shortcut icon", href: "/img/favicon.ico", type: "image/x-icon" }, + ], + ["meta", { name: "msapplication-TileColor", content: "#fff" }], + ["meta", { name: "theme-color", content: "#fff" }], + [ + "meta", + { + name: "viewport", + content: + "width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no", + }, + ], + [ + "meta", + { + property: "description", + content: "Own It. Shape It. Launch It. Evolve your app", + }, + ], + ["meta", { httpEquiv: "Content-Language", content: "en" }], + ["meta", { name: "twitter:card", content: "summary_large_image" }], + ["meta", { name: "twitter:image", content: "/img/Evolve-cover.jpg" }], + ["meta", { name: "twitter:site:domain", content: "ev.xyz" }], + ["meta", { name: "twitter:url", content: "https://ev.xyz" }], + ["meta", { name: "og:image", content: "/img/Evolve-cover.jpg" }], + ["meta", { name: "apple-mobile-web-app-title", content: "Evolve" }], + [ + "script", + { + src: "https://plausible.celestia.org/js/plausible.js", + "data-domain": "ev.xyz", + defer: "", + }, + ], + ], + + // // Build optimizations + // vite: { + // build: { + // rollupOptions: { + // output: { + // manualChunks: (id) => { + // // Extract vendor chunks + // if (id.includes('node_modules')) { + // if (id.includes('vue') || id.includes('@vue')) { + // return 'vue'; + // } + // if (id.includes('mermaid')) { + // return 'mermaid'; + // } + // return 'vendor'; + // } + // }, + // }, + // }, + // // Enable minification + // minify: 'terser', + // terserOptions: { + // compress: { + // drop_console: true, + // drop_debugger: true, + // }, + // }, + // // Optimize chunk size + // chunkSizeWarningLimit: 1000, + // }, + // // Optimize dependencies + // optimizeDeps: { + // include: ['vue', '@vue/runtime-core', '@vue/runtime-dom', '@vue/shared'], + // exclude: ['vitepress'], + // }, + // }, + + themeConfig: { + // https://vitepress.dev/reference/default-theme-config + nav: nav(), + outline: { + level: "deep", + }, + + footer: { + message: "Released under the APACHE-2.0 License", + copyright: "Copyright © 2024 Evolve", + }, + + search: { + provider: "local", + options: { + detailedView: true, + }, + }, + + sidebar: { + "/": sidebarHome(), + }, + + editLink: { + pattern: "https://github.com/evstack/docs/edit/main/:path", + text: "Edit this page on GitHub", + }, + + logo: { + alt: "Evolve Logo", + light: "/img/logo.png", + dark: "/img/logo.png", + }, + + socialLinks: [ + { icon: "github", link: "https://github.com/evstack" }, + { icon: "x", link: "https://twitter.com/ev_stack" }, + { icon: { svg: telegramSVG }, link: "https://t.me/+2p8-IYf6sQ0zNmEx" }, + ], + }, + transformPageData(pageData) { + pageData.frontmatter.head ??= []; + pageData.frontmatter.head.push([ + "meta", + { + name: "og:title", + content: + pageData.frontmatter.layout === "home" + ? `Evolve` + : `${pageData.title} | Evolve`, + }, + { + name: "og:description", + content: pageData.frontmatter.layout === `${pageData.description}`, + }, + ]); + }, +}); + +function nav() { + return [ + { text: "Learn", link: "/learn/about" }, + { text: "How To Guides", link: "/guides/quick-start" }, + // { text: "Blog", link: "/blog/overview" }, + { text: "API Documentation", link: "/api" }, + ]; +} + +function sidebarHome() { + return [ + { + text: "Learn", + collapsed: true, + items: [ + { + text: "About Evolve", + link: "/learn/about", + }, + { + text: "Data Availability", + link: "/learn/data-availability", + }, + { + text: "Sequencing", + collapsed: true, + items: [ + { text: "Overview", link: "/learn/sequencing/overview" }, + { text: "Single", link: "/learn/sequencing/single" }, + ], + }, + { + text: "Execution", + link: "/learn/execution", + }, + { + text: "Technical Specifications", + collapsed: true, + items: [ + { text: "Overview", link: "/learn/specs/overview" }, + { text: "Block Manager", link: "/learn/specs/block-manager" }, + { text: "Block Validity", link: "/learn/specs/block-validity" }, + { text: "Data Availability", link: "/learn/specs/da" }, + { text: "Full Node", link: "/learn/specs/full_node" }, + { text: "Header Sync", link: "/learn/specs/header-sync" }, + { text: "P2P", link: "/learn/specs/p2p" }, + { text: "Store", link: "/learn/specs/store" }, + ], + }, + { text: "Transaction flow", link: "/learn/transaction-flow" }, + { text: "Configuration", link: "/learn/config" }, + ], + }, + { + text: "How To Guides", + collapsed: true, + items: [ + { + text: "Quick start guide", + link: "/guides/quick-start", + }, + { text: "Build a chain", link: "/guides/gm-world" }, + { + text: "DA", + collapsed: true, + items: [ + { + text: "Deploy A Local DA", + link: "/guides/da/local-da", + }, + { + text: "Connect to Celestia", + link: "/guides/da/celestia-da", + }, + ], + }, + // { + // text: "Execution", + // collapsed: true, + // items: [ + // { text: "CosmWasm", link: "/guides/execution/cosmwasm" }, + // ], + // }, + { + text: "Deploy your chain", + collapsed: true, + items: [ + { + text: "Overview", + link: "/guides/deploy/overview", + }, + { + text: "Local (dev)", + link: "/guides/deploy/local", + }, + { + text: "Testnet", + link: "/guides/deploy/testnet", + }, + ], + }, + { + text: "EVM", + collapsed: true, + items: [ + { + text: "Single Sequencer", + link: "/guides/evm/single", + }, + { + text: "Reth State Backup", + link: "/guides/evm/reth-backup", + }, + ], + }, + { + text: "Run a Full Node", + link: "/guides/full-node", + }, + { + text: "Restart your chain", + link: "/guides/restart-chain", + }, + { + text: "Reset your chain's state", + link: "/guides/reset-state", + }, + { + text: "CometBFT into a Evolve app", + link: "/guides/cometbft-to-evolve", + }, + { + text: "Create genesis for your chain", + link: "/guides/create-genesis", + }, + { + text: "Metrics", + link: "/guides/metrics", + }, + { + text: "Use IBC token (TIA) as gas token in your chain", + link: "/guides/use-tia-for-gas", + }, + ], + }, + { + text: "Blog", + collapsed: true, + items: [{ text: "Overview", link: "/blog/overview" }], + }, + { + text: "API Documentation", + collapsed: true, + items: [ + { + text: "Introduction", + link: "/api", + }, + ...sidebar.generateSidebarGroups({ + linkPrefix: "/api/operationsByTags/" + }) + ] + }, + ]; +} diff --git a/docs/.vitepress/constants/constants.js b/docs/.vitepress/constants/constants.js new file mode 100644 index 0000000000..d8b09d4534 --- /dev/null +++ b/docs/.vitepress/constants/constants.js @@ -0,0 +1,18 @@ +const constants = Object.freeze({ + golangVersion: "go1.24.0", + + evolveLatestTag: "v1.0.0-beta.2", + evolveLatestSha: "cd1970de", + evolveIgniteAppVersion: "rollkit/v0.3.0", + + localDALatestTag: "v1.0.0-beta.1", + igniteVersionTag: "v28.5.3", + + celestiaNodeArabicaTag: "v0.23.4-arabica", + celestiaNodeArabicaEvolveTag: "v1.0.0-beta.1", + celestiaNodeMochaTag: "v0.23.4-mocha", + celestiaNodeMochaEvolveTag: "v1.0.0-beta.1", + celestiaNodeMainnetTag: "v0.22.3", + celestiaNodeMainnetEvolveTag: "v1.0.0-beta.1", +}); +export default constants; diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts new file mode 100644 index 0000000000..392e9100a6 --- /dev/null +++ b/docs/.vitepress/theme/index.ts @@ -0,0 +1,18 @@ +// https://vitepress.dev/guide/custom-theme +import { h } from 'vue' +import Theme from 'vitepress/theme' +import './style.css' +import { theme } from 'vitepress-openapi/client' +import 'vitepress-openapi/dist/style.css' + +export default { + extends: Theme, + Layout: () => { + return h(Theme.Layout, null, { + // https://vitepress.dev/guide/extending-default-theme#layout-slots + }) + }, + enhanceApp({ app, router, siteData }) { + theme.enhanceApp({ app, router, siteData }) + } +} diff --git a/docs/.vitepress/theme/style.css b/docs/.vitepress/theme/style.css new file mode 100644 index 0000000000..eb971f6459 --- /dev/null +++ b/docs/.vitepress/theme/style.css @@ -0,0 +1,413 @@ +/** + * Customize default theme styling by overriding CSS variables: + * https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css + */ + +/* Import Evolve brand fonts */ +@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500;600&display=swap"); + +/** + * Colors + * -------------------------------------------------------------------------- */ + +:root { + --vp-c-brand: #ff0033; + --vp-c-brand-light: #ff3355; + --vp-c-brand-lighter: #ff6677; + --vp-c-brand-lightest: #ffccdd; + --vp-c-brand-dark: #cc0029; + --vp-c-brand-darker: #990020; + --vp-c-brand-dimm: rgba(255, 0, 51, 0.08); + + /* Additional Evolve brand colors */ + --vp-c-bg: #0a0a0a; + --vp-c-bg-soft: #141414; + --vp-c-bg-mute: #1a1a1a; + --vp-c-slate: #475569; + --vp-c-violet: #4c1d95; + --vp-c-violet-light: #6d28d9; +} + +/** + * Component: Button + * -------------------------------------------------------------------------- */ + +:root { + --vp-button-brand-border: var(--vp-c-brand-light); + --vp-button-brand-text: var(--vp-c-white); + --vp-button-brand-bg: var(--vp-c-brand); + --vp-button-brand-hover-border: var(--vp-c-brand-light); + --vp-button-brand-hover-text: var(--vp-c-white); + --vp-button-brand-hover-bg: var(--vp-c-brand-light); + --vp-button-brand-active-border: var(--vp-c-brand-light); + --vp-button-brand-active-text: var(--vp-c-white); + --vp-button-brand-active-bg: var(--vp-button-brand-bg); +} + +/** + * Component: Home + * -------------------------------------------------------------------------- */ + +:root { + --vp-home-hero-name-color: transparent; + --vp-home-hero-name-background: -webkit-linear-gradient( + 120deg, + #ff0033 30%, + #6d28d9 + ); + + /* Remove gradient background for hero image */ + --vp-home-hero-image-background-image: none; + --vp-home-hero-image-filter: none; +} + +@media (min-width: 640px) { + :root { + --vp-home-hero-image-filter: none; + } +} + +@media (min-width: 960px) { + :root { + --vp-home-hero-image-filter: none; + } +} + +/** + * Component: Custom Block + * -------------------------------------------------------------------------- */ + +:root { + --vp-custom-block-tip-border: var(--vp-c-brand); + --vp-custom-block-tip-text: var(--vp-c-brand-darker); + --vp-custom-block-tip-bg: var(--vp-c-brand-dimm); +} + +.dark { + --vp-custom-block-tip-border: var(--vp-c-brand); + --vp-custom-block-tip-text: var(--vp-c-brand-lightest); + --vp-custom-block-tip-bg: var(--vp-c-brand-dimm); +} + +/** + * Component: Algolia + * -------------------------------------------------------------------------- */ + +.DocSearch { + --docsearch-primary-color: var(--vp-c-brand) !important; +} + +/** + * Typography + * -------------------------------------------------------------------------- */ + +:root { + --vp-font-family-base: + "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, + Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", + sans-serif; + --vp-font-family-mono: + "IBM Plex Mono", source-code-pro, Menlo, Monaco, Consolas, + "Courier New", monospace; +} + +/** + * Dark Mode Adjustments + * -------------------------------------------------------------------------- */ + +.dark { + --vp-c-bg: #000000; + --vp-c-bg-soft: #0a0a0a; + --vp-c-bg-mute: #141414; + --vp-c-bg-alt: #000000; +} + +/** + * Homepage Customizations + * -------------------------------------------------------------------------- */ + +/* Center align hero text and buttons */ +.VPHero .VPHomeHero { + text-align: center; +} + +.VPHero .name, +.VPHero .text, +.VPHero .tagline { + text-align: center !important; + margin-left: auto; + margin-right: auto; +} + +/* Center the action buttons */ +.VPHero .actions { + justify-content: center !important; + display: flex !important; + gap: 16px; +} + +.VPHero .VPButton { + margin: 0 !important; +} + +/* Simple grid background - applied to body only */ +body { + background-color: #ffffff; + background-image: + linear-gradient(#ff0033 1px, transparent 1px), + linear-gradient(90deg, #ff0033 1px, transparent 1px); + background-size: 60px 60px; + background-attachment: fixed; +} + +.dark body { + background-color: #000000; +} + +/* Adjust grid opacity for light/dark modes with thicker lines */ +body { + background-image: + linear-gradient(rgba(255, 0, 51, 0.12) 3px, transparent 3px), + linear-gradient(90deg, rgba(255, 0, 51, 0.12) 3px, transparent 3px); +} + +.dark body { + background-image: + linear-gradient(rgba(255, 0, 51, 0.15) 3px, transparent 3px), + linear-gradient(90deg, rgba(255, 0, 51, 0.15) 3px, transparent 3px); +} + +/* Style the hero image (logo) */ +.VPHero .VPImage { + display: block; + margin: 0 auto; +} + +/* Make the hero logo bigger */ +.VPHero .VPImage img { + height: 120px !important; + width: auto !important; + max-width: none !important; +} + +/* Make all layout components transparent to show body background */ +.Layout, +.VPContent, +.VPDoc, +.VPHome { + background-color: transparent !important; +} + +/* Make content areas transparent by default to show body grid background */ +.VPContent, +.VPHome, +.Layout > * { + background-color: transparent !important; + background: transparent !important; +} + +/* Documentation pages - solid background for readability */ +.VPDoc { + background-color: #ffffff !important; + min-height: 100vh; +} + +.dark .VPDoc { + background-color: #0a0a0a !important; +} + +/* Documentation content area */ +.VPDoc .container, +.VPDoc .content, +.VPDocContent { + background-color: #ffffff !important; +} + +.dark .VPDoc .container, +.dark .VPDoc .content, +.dark .VPDocContent { + background-color: #0a0a0a !important; +} + +/* Add padding to doc content for better readability */ +.VPDoc .VPDocOutlineDropdown, +.VPDoc .content-container { + padding: 1rem; +} + +/* Sidebar background for documentation pages */ +.VPSidebar { + background-color: rgba(255, 255, 255, 0.95) !important; + backdrop-filter: blur(8px); +} + +.dark .VPSidebar { + background-color: rgba(10, 10, 10, 0.95) !important; + backdrop-filter: blur(8px); +} + +/* Feature boxes - ensure proper backgrounds in light/dark modes */ +.VPFeature { + background-color: #ffffff !important; + border-color: #e5e5e5 !important; +} + +.dark .VPFeature { + background-color: #0a0a0a !important; + border-color: #2a2a2a !important; +} + +/* Ensure all VitePress components respect light/dark backgrounds */ +:root { + --vp-c-bg: #ffffff; + --vp-c-bg-soft: #f6f6f6; + --vp-c-bg-mute: #f0f0f0; +} + +/* Fix navbar backgrounds - more specific targeting including scroll states */ +.VPNav, +.VPNav .VPNavBar, +.VPNavBar, +header.VPNav, +.VPNav.scrolled, +.VPNavBar.scrolled, +.VPNav.filled, +.VPNavBar.filled { + background-color: rgba(255, 255, 255, 0.8) !important; + backdrop-filter: blur(12px); + border-bottom: 1px solid rgba(0, 0, 0, 0.1) !important; +} + +.dark .VPNav, +.dark .VPNav .VPNavBar, +.dark .VPNavBar, +.dark header.VPNav, +.dark .VPNav.scrolled, +.dark .VPNavBar.scrolled, +.dark .VPNav.filled, +.dark .VPNavBar.filled { + background-color: rgba(0, 0, 0, 0.8) !important; + backdrop-filter: blur(12px); + border-bottom: 1px solid rgba(255, 0, 51, 0.2) !important; +} + +/* Target the main nav container */ +.VPNavBar.has-sidebar, +.VPNavBar.no-sidebar { + background-color: inherit !important; +} + +.VPLocalNav { + background-color: rgba(255, 255, 255, 0.8) !important; + backdrop-filter: blur(12px); + border-bottom: 1px solid rgba(0, 0, 0, 0.1) !important; +} + +.dark .VPLocalNav { + background-color: rgba(0, 0, 0, 0.8) !important; + backdrop-filter: blur(12px); + border-bottom: 1px solid rgba(255, 0, 51, 0.2) !important; +} + +/* Footer styling with grid background */ +.VPFooter { + background-color: #ffffff !important; + border-top: 1px solid rgba(0, 0, 0, 0.1) !important; + position: relative; +} + +.dark .VPFooter { + background-color: #000000 !important; + border-top: 1px solid rgba(255, 0, 51, 0.2) !important; +} + +/* Footer also transparent to show body grid background */ +.VPFooter .VPFooterCopyright { + background-color: transparent; + padding: 8px 16px; +} + +/* Ensure nav screen (mobile menu) also has correct background */ +.VPNavScreen { + background-color: #ffffff !important; +} + +.dark .VPNavScreen { + background-color: #000000 !important; +} + +/* Override VitePress default nav styles completely */ +html.dark { + --vp-nav-bg-color: rgba(0, 0, 0, 0.8) !important; + --vp-c-bg: #000000 !important; + --vp-c-bg-soft: #000000 !important; +} + +html:not(.dark) { + --vp-nav-bg-color: rgba(255, 255, 255, 0.8) !important; + --vp-c-bg: #ffffff !important; + --vp-c-bg-soft: #ffffff !important; +} + +/* Force nav background using CSS variables */ +:root { + --vp-nav-bg-color: rgba(255, 255, 255, 0.8); + --vp-nav-height: 55px; +} + +.dark { + --vp-nav-bg-color: rgba(0, 0, 0, 0.8); +} + +/* Apply the variable to nav elements (excluding children to preserve theme toggle) */ +.VPNav, +.VPNavBar, +html .VPNav, +html .VPNavBar, +html.dark .VPNav, +html.dark .VPNavBar { + background: var(--vp-nav-bg-color) !important; +} + +/* Ensure nav stays consistent during scroll transitions */ +.VPNav[data-scrolled="true"], +.VPNavBar[data-scrolled="true"] { + background: var(--vp-nav-bg-color) !important; +} + +/** + * Custom Logo Styling + * -------------------------------------------------------------------------- */ + +/* Make the logo bigger */ +.VPNavBarTitle .VPImage { + height: 55px !important; + width: auto !important; +} + +/* Adjust logo container */ +.VPNavBarTitle { + display: flex; + align-items: center; +} + +/* Remove any max width constraints on the logo */ +.VPNavBarTitle .logo { + max-width: none !important; + height: 55px !important; +} + +/* Ensure the logo link takes full height */ +.VPNavBarTitle a { + display: flex; + align-items: center; + height: 100%; +} + +/* Make sure the image inside logo takes full size */ +.VPNavBarTitle img { + height: 55px !important; + width: auto !important; + max-height: 55px !important; +} + diff --git a/docs/CLAUDE.md b/docs/CLAUDE.md new file mode 100644 index 0000000000..4633e357e9 --- /dev/null +++ b/docs/CLAUDE.md @@ -0,0 +1,64 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Common Development Commands + +### Local Development + +- `yarn install` - Install dependencies +- `yarn dev` - Start VitePress development server (hot reload enabled) +- `yarn build` - Build static documentation site +- `yarn preview` - Preview built site locally +- `make testlink` - Validate all links in markdown files using lychee + +### Deployment + +- Automatic deployment via GitHub Actions on push to main branch +- Preview deployments available for pull requests + +## High-Level Architecture + +This is a **VitePress-based documentation site** for Evolve. Key architectural elements: + +### Content Organization + +``` +docs/ +├── .vitepress/config.ts # Site configuration, navigation, theme +├── blog/ # Blog posts and announcements +├── guides/ # Step-by-step tutorials +│ ├── da/ # Data availability guides +│ ├── deploy/ # Deployment guides +│ ├── evm/ # EVM integration guides +│ └── execution/ # Execution layer guides +├── learn/ # Technical documentation +│ ├── sequencing/ # Sequencing concepts +│ └── specs/ # Technical specifications +└── public/ # Static assets and installation scripts +``` + +### Key Technical Details + +- **Static Site Generator**: VitePress with Mermaid diagram support +- **Navigation Structure**: Configured in `.vitepress/config.ts` with collapsible sidebar sections +- **Analytics**: Plausible analytics and Chatbase integration +- **Content Format**: Markdown files with frontmatter support +- **Link Validation**: Automated via `make testlink` and GitHub Actions + +### Development Workflow + +1. Content changes: Edit markdown files in appropriate directories +2. Navigation changes: Update `.vitepress/config.ts` +3. Test locally with `yarn dev` +4. Validate links with `make testlink` +5. Create PR - preview deployment will be available +6. Merge to main triggers automatic deployment + +### Important Conventions + +- Use relative links for internal documentation references +- Place images in `/public/img/` +- Blog posts should include proper frontmatter with date and author +- Guides should be structured with clear step-by-step instructions +- Technical documentation in `/learn` should be comprehensive and accurate diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000..2b98a793c7 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,40 @@ +[![Deploy](https://github.com/evstack/ev-node/actions/workflows/deploy.yml/badge.svg)](https://github.com/evstack/docs/actions/workflows/deploy.yml) + +# Evolve Documentation Site + +Welcome to the official documentation repository for Evolve. + +Here you'll find comprehensive guides, and reference materials to help you make the most out of Evolve. + +## Building the site + +To get started, clone the repository and run the following: + +```bash +yarn run dev +``` + +This documentation site is built with [VitePress](https://vitepress.dev) + +## Contribution Guidelines + +We love contributions from the community! Whether you're fixing typos, improving content clarity, or adding new topics, every contribution helps. + +* Fork & Clone: Fork this repository and clone it to your local machine. +* Branch: Always create a new branch for your changes. Naming it relevantly. +* Commit Changes: Make your changes and commit them with a clear and concise commit message. +* Push & Create PR: Push your changes to your fork and create a pull request to the main branch of this repository. + +Please ensure you review the detailed Contribution Guidelines above before making a pull request. + +## Directory Structure + +* /guides: Step-by-step instructions to help users build their own chains with Evolve. +* /learn: Technical reference materials, such as configuration options and details about the Evolve stack. +* /blog: Blog posts for the Evolve blog. + +* /public: Images, diagrams, and other media files used in the documentation. + +## Feedback & Suggestions + +We value feedback from the community. If you have suggestions for improvements or find any discrepancies in the documentation, please raise an issue in this repository. diff --git a/docs/adr/adr-001-node-interface.md b/docs/adr/adr-001-node-interface.md index a2159013e4..7671d9cb1a 100644 --- a/docs/adr/adr-001-node-interface.md +++ b/docs/adr/adr-001-node-interface.md @@ -1,10 +1,10 @@ -# Using Rollkit `Node` as replacement of Tendermint `Node` +# Using Evolve `Node` as replacement of Tendermint `Node` ## Changelog - 26.02.2021: Initial Draft - 29.09.2022: Rename Optimint to rollmint -- 22.01.2023: Rename rollmint to Rollkit +- 22.01.2023: Rename rollmint to Evolve Replacing on the `Node` level gives much flexibility. Still, significant amount of code can be reused, and there is no need to refactor lazyledger-core. Cosmos SDK is tightly coupled with Tendermint with regards to node creation, RPC, app initialization, etc. De-coupling requires big refactoring of cosmos-sdk. @@ -34,7 +34,7 @@ We don't need to introduce common interface `Node`s, because the plan is to use - Pros: - May be possible to avoid Tendermint issues - - Should be possible to avoid dependency on Tendermint in Rollkit + - Should be possible to avoid dependency on Tendermint in Evolve - Changes probably limited to cosmos-sdk (not required in tendermint/lazyledger-core) - Cons: - Reinventing the wheel @@ -52,4 +52,4 @@ easier. ## Development -`cosmos-sdk-rollmit` is a repository dedicated for maintenance of Rollkit-enabled version of Cosmos SDK. +`cosmos-sdk-rollmit` is a repository dedicated for maintenance of Evolve-enabled version of Cosmos SDK. diff --git a/docs/adr/adr-003-peer-discovery.md b/docs/adr/adr-003-peer-discovery.md index 4c2ebc87ec..4510013479 100644 --- a/docs/adr/adr-003-peer-discovery.md +++ b/docs/adr/adr-003-peer-discovery.md @@ -10,7 +10,7 @@ Libp2p provides multiple ways to discover peers (DHT, mDNS, PubSub peer exchange ## Proposed network architecture -1. There will be a set of well-known, application-agnostic seed nodes. Every Rollkit client will be able to connect to such node, addresses will be saved in configuration. +1. There will be a set of well-known, application-agnostic seed nodes. Every Evolve client will be able to connect to such node, addresses will be saved in configuration. - This does not limit applications as they can still create independent networks with separate set of seed nodes. 2. Nodes in the network will serve DHT. It will be used for active peer discovery. Client of each optimistic network will be able to find other peers in this particular network. - All nodes will cooperate on the same DHT. diff --git a/docs/adr/adr-015-rollkit-minimal-header.md b/docs/adr/adr-015-rollkit-minimal-header.md index b423bfce37..1b7793f228 100644 --- a/docs/adr/adr-015-rollkit-minimal-header.md +++ b/docs/adr/adr-015-rollkit-minimal-header.md @@ -10,7 +10,7 @@ The Rollkit minimal header is a streamlined version of the traditional header, f ### Rollkit Minimal Header Structure -```ascii +```txt ┌─────────────────────────────────────────────┐ │ Rollkit Minimal Header │ ├─────────────────────┬───────────────────────┤ @@ -69,7 +69,7 @@ This minimal Rollkit header can be transformed to be tailored to a specific exec #### Transformation to EVM Header -```ascii +```txt ┌─────────────────────────────────────────────┐ │ Rollkit Minimal Header │ └───────────────────┬─────────────────────────┘ @@ -118,7 +118,7 @@ This header can be transformed into an ABCI-specific header for IBC compatibilit #### Transformation to ABCI Header -```ascii +```txt ┌─────────────────────────────────────────────┐ │ Rollkit Minimal Header │ └───────────────────┬─────────────────────────┘ @@ -163,7 +163,7 @@ This header can be transformed into an ABCI-specific header for IBC compatibilit ### Header Transformation Flow -```ascii +```txt ┌─────────────────────────────────────────────┐ │ Rollkit Minimal Header │ │ │ diff --git a/docs/adr/adr-018-rpc.md b/docs/adr/adr-018-rpc.md index 59b790f042..5301ace37a 100644 --- a/docs/adr/adr-018-rpc.md +++ b/docs/adr/adr-018-rpc.md @@ -7,7 +7,7 @@ ## Context -The Rollkit store package provides a critical interface for storing and retrieving blocks, commits, and state data. Currently, this functionality is only available locally through direct Go package imports. To enable remote access to this data and improve the system's scalability and interoperability, we need to implement a remote procedure call (RPC) layer. +The Evolve store package provides a critical interface for storing and retrieving blocks, commits, and state data. Currently, this functionality is only available locally through direct Go package imports. To enable remote access to this data and improve the system's scalability and interoperability, we need to implement a remote procedure call (RPC) layer. Connect-Go has been chosen as the RPC framework due to its modern features, excellent developer experience, and compatibility with both gRPC and HTTP/1.1 protocols. @@ -36,7 +36,7 @@ Implement a Connect-Go service layer that exposes the Store interface functional ```protobuf syntax = "proto3"; -package rollkit.store.v1; +package evnode.store.v1; message Block { SignedHeader header = 1; @@ -68,7 +68,7 @@ service StoreService { ### Implementation Structure -```tree +```txt pkg/ rpc/ server/ diff --git a/docs/adr/adr-019-forced-inclusion-mechanism.md b/docs/adr/adr-019-forced-inclusion-mechanism.md index e5db1cd253..378dd9b17f 100644 --- a/docs/adr/adr-019-forced-inclusion-mechanism.md +++ b/docs/adr/adr-019-forced-inclusion-mechanism.md @@ -7,11 +7,11 @@ ## Context -Rollkit currently supports a single sequencer implementation as described in ADR-013. While this approach provides a simple and efficient solution, it introduces a single point of failure that can impact the liveness of the network. If the sequencer goes down or becomes unresponsive, the chain cannot progress. +Evolve currently supports a single sequencer implementation as described in ADR-013. While this approach provides a simple and efficient solution, it introduces a single point of failure that can impact the liveness of the network. If the sequencer goes down or becomes unresponsive, the chain cannot progress. -To address this limitation and improve the liveness properties of applications built with Rollkit, we propose implementing a forced inclusion mechanism. This mechanism will allow transactions to be included directly from the Data Availability (DA) layer when the sequencer is unresponsive, creating an "unstoppable" property for Rollkit-based chains. +To address this limitation and improve the liveness properties of applications built with Evolve, we propose implementing a forced inclusion mechanism. This mechanism will allow transactions to be included directly from the Data Availability (DA) layer when the sequencer is unresponsive, creating an "unstoppable" property for Evolve-based chains. -This enhancement aligns with the requirements defined in the [L2 Beat framework](https://forum.l2beat.com/t/the-stages-framework/291#p-516-stage-1-requirements-3) for Stage 1 L2s, advancing Rollkit's capabilities as a robust sequencer library. +This enhancement aligns with the requirements defined in the [L2 Beat framework](https://forum.l2beat.com/t/the-stages-framework/291#p-516-stage-1-requirements-3) for Stage 1 L2s, advancing Evolve's capabilities as a robust sequencer library. ## Alternative Approaches @@ -25,13 +25,13 @@ Another approach would be to implement an automatic failover mechanism where bac ## Decision -We will implement a forced inclusion mechanism for the Rollkit single sequencer architecture that uses a time-based inclusion delay approach. This approach will: +We will implement a forced inclusion mechanism for the Evolve single sequencer architecture that uses a time-based inclusion delay approach. This approach will: 1. Track when transactions are first seen in terms of DA block time 2. Require a minimum number of DA blocks to pass before including a direct transaction 3. Let full nodes enforce inclusion within a fixed period of time window -The mechanism will be designed to maintain backward compatibility with existing Rollkit deployments while providing enhanced liveness guarantees. +The mechanism will be designed to maintain backward compatibility with existing Evolve deployments while providing enhanced liveness guarantees. ### High-Level Architecture @@ -85,7 +85,7 @@ flowchart TB ### Systems Affected -The implementation of the forced inclusion mechanism will affect several components of the Rollkit framework: +The implementation of the forced inclusion mechanism will affect several components of the Evolve framework: 1. **Single Sequencer**: Must be modified to track and include direct transactions from the DA layer within the time window and after minimum DA block delay 2. **Full Node**: Must be updated to recognize and validate blocks with forced inclusions @@ -189,7 +189,7 @@ func (n *Node) ValidateBlockTimeWindow(ctx context.Context, block *types.Block) The following diagram illustrates the operation flow for the sequencer with forced inclusion: -```ascii +```txt ┌─────────────────────────────────────────────────────────────────────────────────┐ │ Sequencer Operation Flow │ └─────────────────┬───────────────────────────────────────────────────────────────┘ @@ -235,7 +235,7 @@ The following diagram illustrates the operation flow for the sequencer with forc The following diagram illustrates the operation flow for full nodes with forced inclusion support: -```ascii +```txt ┌─────────────────────────────────────────────────────────────────────────────────┐ │ Full Node Operation Flow │ └─────────────────────────────────────────────────────────────────────────────────┘ @@ -410,8 +410,8 @@ Proposed ### Positive -- Improves the liveness guarantees of Rollkit-based chains -- Provides a path for Rollkit to meet Stage 1 L2 requirements per the L2 Beat framework +- Improves the liveness guarantees of Evolve-based chains +- Provides a path for Evolve to meet Stage 1 L2 requirements per the L2 Beat framework - Creates an "unstoppable" property for applications, enhancing their reliability - Maintains a deterministic chain state regardless of sequencer availability - More predictable deadlines in DA time @@ -436,7 +436,7 @@ Proposed ## References -- [Rollkit Single Sequencer ADR-013](https://github.com/evstack/ev-node/blob/main/docs/adr/adr-013-single-sequencer.md) -- [Rollkit Minimal Header ADR-015](https://github.com/evstack/ev-node/blob/main/docs/adr/adr-015-rollkit-minimal-header.md) +- [Evolve Single Sequencer ADR-013](https://github.com/evstack/ev-node/blob/main/docs/adr/adr-013-single-sequencer.md) +- [Evolve Minimal Header ADR-015](https://github.com/evstack/ev-node/blob/main/docs/adr/adr-015-rollkit-minimal-header.md) - [L2 Beat Stages Framework](https://forum.l2beat.com/t/the-stages-framework/291#p-516-stage-1-requirements-3) - [GitHub Issue #1914: Add Forced Inclusion Mechanism from the DA layer](https://github.com/evstack/ev-node/issues/1914) diff --git a/docs/adr/adr-021-lazy-aggregation.md b/docs/adr/adr-021-lazy-aggregation.md index d0342d738b..9071cac13e 100644 --- a/docs/adr/adr-021-lazy-aggregation.md +++ b/docs/adr/adr-021-lazy-aggregation.md @@ -8,7 +8,7 @@ ## Context -Rollkit's lazy aggregation mechanism currently produces blocks at set intervals when no transactions are present, and immediately when transactions are available. However, this approach creates inconsistency with the DA layer (Celestia) as empty blocks are not posted to the DA layer. This breaks the expected 1:1 mapping between DA layer blocks and execution layer blocks in EVM environments. +Evolve's lazy aggregation mechanism currently produces blocks at set intervals when no transactions are present, and immediately when transactions are available. However, this approach creates inconsistency with the DA layer (Celestia) as empty blocks are not posted to the DA layer. This breaks the expected 1:1 mapping between DA layer blocks and execution layer blocks in EVM environments. ## Decision @@ -200,7 +200,7 @@ Implemented ### Neutral - Requires careful handling of batch timestamps -- Maintains backward compatibility with existing Rollkit deployments +- Maintains backward compatibility with existing Evolve deployments ## References diff --git a/docs/adr/adr-022-validator-network.md b/docs/adr/adr-022-validator-network.md index a2ce364df9..a42a4c424f 100644 --- a/docs/adr/adr-022-validator-network.md +++ b/docs/adr/adr-022-validator-network.md @@ -13,7 +13,7 @@ The original design and implementation was centered around IBC and adding an ext ## Decision -Rollkit will introduce a validator network in which there will be a set of validators verifying execution and construction. +Evolve will introduce a validator network in which there will be a set of validators verifying execution and construction. Validators sign **one Attestation per epoch** that covers every block proposed inside that epoch. The Attestation must be broadcast as a transaction within a configurable @@ -56,11 +56,11 @@ The attester layer can plug into different validator‑set providers. Below we o #### Cosmos‑SDK -Introduce a dedicated x/network module that completely owns the CommitHash and ValidatorHash that appear in every block‑header. Rollkit remains untouched; the logic lives entirely in the ABCI application. +Introduce a dedicated x/network module that completely owns the CommitHash and ValidatorHash that appear in every block‑header. Evolve remains untouched; the logic lives entirely in the ABCI application. Hashes produced in‑app During EndBlock, x/network gathers the attestation bitmap for height h, computes and returns them in ResponseEndBlock. -When a relayer queries /block or /header, the application serves the canonical valset hash and commit hash from its KV‑store, ensuring external clients see the attested header even though rollkit itself never verified the signatures. +When a relayer queries /block or /header, the application serves the canonical valset hash and commit hash from its KV‑store, ensuring external clients see the attested header even though Evolve itself never verified the signatures. Validatorset updates from the staking module (x/staking) remains the single source of truth for bonded power. Every block it emits a ValidatorSetUpdate event. x/network subscribes and mirrors the active validator bitmap. On a set‑change (say at height 100) the EndBlock hook updates x/network's bitmap before computing the hashes for the next height. @@ -71,7 +71,7 @@ the active validator bitmap. On a set‑change (say at height 100) the EndBlock sequenceDiagram participant Val as Validator participant App as x/network - participant R as Rollkit + participant R as Evolve Val->>App: MsgAttest{h, sig} loop within epoch App->>App: store sig, update bitmap @@ -93,7 +93,7 @@ Missing participation at the epoch boundary x/network evaluates participation: Solidity Contract -```sol +```txt contract StakeManager { struct Validator { uint96 power; bytes32 edKey; bytes blsKey; } mapping(address => Validator) public validators; diff --git a/docs/api/index.md b/docs/api/index.md new file mode 100644 index 0000000000..694987ac7d --- /dev/null +++ b/docs/api/index.md @@ -0,0 +1,11 @@ +--- +aside: false +outline: false +title: API Introduction +--- + + + + \ No newline at end of file diff --git a/docs/api/operationsByTags/[operationId].md b/docs/api/operationsByTags/[operationId].md new file mode 100644 index 0000000000..f80e6c2ed1 --- /dev/null +++ b/docs/api/operationsByTags/[operationId].md @@ -0,0 +1,16 @@ +--- +aside: false +outline: false +title: API Operation Details +--- + + + + \ No newline at end of file diff --git a/docs/api/operationsByTags/[operationId].paths.js b/docs/api/operationsByTags/[operationId].paths.js new file mode 100644 index 0000000000..c36221e738 --- /dev/null +++ b/docs/api/operationsByTags/[operationId].paths.js @@ -0,0 +1,17 @@ +import { usePaths } from 'vitepress-openapi' +import spec from '../../src/openapi-rpc.json' with {type: 'json'} + +export default { + paths() { + return usePaths({ spec }) + .getPathsByVerbs() + .map(({ operationId, summary }) => { + return { + params: { + operationId, + pageTitle: `${summary} - vitepress-openapi`, + }, + } + }) + }, +} \ No newline at end of file diff --git a/docs/guides/cometbft-to-evolve.md b/docs/guides/cometbft-to-evolve.md new file mode 100644 index 0000000000..eb6e208ad2 --- /dev/null +++ b/docs/guides/cometbft-to-evolve.md @@ -0,0 +1,73 @@ +# How to Turn Your CometBFT App into an Evolve App + +This guide will walk you through the process of turning your existing CometBFT app into an Evolve app. By integrating Evolve into your CometBFT-based blockchain, you can leverage enhanced modularity and data availability features. + + + + +This guide assumes you have a CometBFT app set up and [Ignite CLI](https://docs.ignite.com) installed. + +:::warning +This tutorial is currently being updated to reflect the latest changes using the evolve ignite app. +Please check back later for the updated version. +::: + +## Install Evolve {#install-evolve} + +You need to install Evolve in your CometBFT app. Open a terminal in the directory where your app is located and run the following command: + +```bash-vue +ignite app install github.com/ignite/apps/evolve@{{constants.evolveIgniteAppVersion}} +``` + +## Add Evolve Features to Your CometBFT App {#add-evolve-features} + +Now that Evolve is installed, you can add Evolve features to your existing blockchain app. Run the following command to integrate Evolve: + +```bash +ignite evolve add +``` + +## Initialize Evolve {#initialize-evolve} + +To prepare your app for Evolve, you'll need to initialize it. + +Run the following command to initialize Evolve: + +```bash +ignite evolve init +``` + + + diff --git a/docs/guides/create-genesis.md b/docs/guides/create-genesis.md new file mode 100644 index 0000000000..cf14c59226 --- /dev/null +++ b/docs/guides/create-genesis.md @@ -0,0 +1,121 @@ +# How to create a genesis for your chain + +This guide will walk you through the process of setting up a genesis for your chain. Follow the steps below to initialize your chain, add a genesis account, and start the chain. + +## Pre-requisities + +For this guide you need to have a chain directory where you have created and built your chain. + +If you don't have a chain directory yet, you can initialize a simple ignite chain by following [this tutorial](/guides/gm-world.md) + +:::tip +This guide will use the simple ignite chain created in linked guide. Make sure to update any relevant variables to match your chain. +::: + +## 1. Setting variables + +First, set the necessary variables for your chain in the terminal, here is an example: + +```sh +VALIDATOR_NAME=validator1 +CHAIN_ID=gm +KEY_NAME=chain-key +CHAINFLAG="--chain-id ${CHAIN_ID}" +TOKEN_AMOUNT="10000000000000000000000000stake" +STAKING_AMOUNT="1000000000stake" +``` + +## Rebuild your chain + +Ensure that `.gm` folder is present at `/Users/you/.gm` (if not, follow a [Guide](/guides/gm-world.md) to set it up) and run the following command to (re)generate an entrypoint binary out of the code: + +```sh +make install +``` + +Once completed, run the following command to ensure that the `/Users/you/.gm` directory is present: + +```sh +ignite evolve init +``` + +This (re)creates an `gmd` binary that will be used for the rest of the tutorials to run all the operations on the chain. + +## Resetting existing genesis/chain data + +Reset any existing chain data: + +```sh +gmd comet unsafe-reset-all +``` + +Reset any existing genesis data: + +```sh +rm -rf $HOME/.$CHAIN_ID/config/gentx +rm $HOME/.$CHAIN_ID/config/genesis.json +``` + +## Initializing the validator + +Initialize the validator with the chain ID you set: + +```sh +gmd init $VALIDATOR_NAME --chain-id $CHAIN_ID +``` + +## Adding a key to keyring backend + +Add a key to the keyring-backend: + +```sh +gmd keys add $KEY_NAME --keyring-backend test +``` + +## Adding a genesis account + +Add a genesis account with the specified token amount: + +```sh +gmd genesis add-genesis-account $KEY_NAME $TOKEN_AMOUNT --keyring-backend test +``` + +## Setting the staking amount in the genesis transaction + +Set the staking amount in the genesis transaction: + +```sh +gmd genesis gentx $KEY_NAME $STAKING_AMOUNT --chain-id $CHAIN_ID --keyring-backend test +``` + +## Collecting genesis transactions + +Collect the genesis transactions: + +```sh +gmd genesis collect-gentxs +``` + +## Configuring the genesis file + +Copy the centralized sequencer address into `genesis.json`: + +```sh +ADDRESS=$(jq -r '.address' ~/.$CHAIN_ID/config/priv_validator_key.json) +PUB_KEY=$(jq -r '.pub_key' ~/.$CHAIN_ID/config/priv_validator_key.json) +jq --argjson pubKey "$PUB_KEY" '.consensus["validators"]=[{"address": "'$ADDRESS'", "pub_key": $pubKey, "power": "1000", "name": "Evolve Sequencer"}]' ~/.$CHAIN_ID/config/genesis.json > temp.json && mv temp.json ~/.$CHAIN_ID/config/genesis.json +``` + +## Starting the chain + +Finally, start the chain with your start command. + +For example, start the simple ignite chain with the following command: + +```sh +gmd start --evolve.node.aggregator --chain_id $CHAIN_ID +``` + +## Summary + +By following these steps, you will set up the genesis for your chain, initialize the validator, add a genesis account, and started the chain. This guide provides a basic framework for configuring and starting your chain using the gm-world binary. Make sure you initialized your chain correctly, and use the `gmd` command for all operations. diff --git a/docs/guides/da/celestia-da.md b/docs/guides/da/celestia-da.md new file mode 100644 index 0000000000..f017e6e7b2 --- /dev/null +++ b/docs/guides/da/celestia-da.md @@ -0,0 +1,155 @@ +# Using Celestia as DA + + + + +## 🌞 Introduction {#introduction} + +This tutorial serves as a comprehensive guide for deploying your chain on Celestia's data availability (DA) network. From the Evolve perspective, there's no difference in posting blocks to Celestia's testnets or Mainnet Beta. + +Before proceeding, ensure that you have completed the [gm-world](/guides/gm-world.md) tutorial, which covers installing the Testapp CLI and running a chain against a local DA network. + +## 🪶 Running a Celestia light node + +Before you can start your chain node, you need to initiate, sync, and fund a light node on one of Celestia's networks on a compatible version: + +Find more information on how to run a light node in the [Celestia documentation](https://celestia.org/run-a-light-node/#start-up-a-node). + +::: code-group + +```sh-vue [Arabica] +Evolve Version: {{constants.celestiaNodeArabicaEvolveTag}} +Celestia Node Version: {{constants.celestiaNodeArabicaTag}} +``` + +```sh-vue [Mocha] +Evolve Version: {{constants.celestiaNodeMochaEvolveTag}} +Celestia Node Version: {{constants.celestiaNodeMochaTag}} +``` + +```sh-vue [Mainnet] +Evolve Version: {{constants.celestiaNodeMainnetEvolveTag}} +Celestia Node Version: {{constants.celestiaNodeMainnetTag}} +``` + +::: + +- [Arabica Devnet](https://docs.celestia.org/how-to-guides/arabica-devnet) +- [Mocha Testnet](https://docs.celestia.org/how-to-guides/mocha-testnet) +- [Mainnet Beta](https://docs.celestia.org/how-to-guides/mainnet) + +The main difference lies in how you fund your wallet address: using testnet TIA or [TIA](https://docs.celestia.org/learn/tia#overview-of-tia) for Mainnet Beta. + +After successfully starting a light node, it's time to start posting the batches of blocks of data that your chain generates to Celestia. + +## 🏗️ Prerequisites {#prerequisites} + +- `gmd` CLI installed from the [gm-world](/guides/gm-world.md) tutorial. + +## 🛠️ Configuring flags for DA + +Now that we are posting to the Celestia DA instead of the local DA, the `evolve start` command requires three DA configuration flags: + +- `--evolve.da.start_height` +- `--evolve.da.auth_token` +- `--evolve.da.namespace` + +:::tip +Optionally, you could also set the `--evolve.da.block_time` flag. This should be set to the finality time of the DA layer, not its actual block time, as Evolve does not handle reorganization logic. The default value is 15 seconds. +::: + +Let's determine which values to provide for each of them. + +First, let's query the DA layer start height using our light node. + +```bash +DA_BLOCK_HEIGHT=$(celestia header network-head | jq -r '.result.header.height') +echo -e "\n Your DA_BLOCK_HEIGHT is $DA_BLOCK_HEIGHT \n" +``` + +The output of the command above will look similar to this: + +```bash + Your DA_BLOCK_HEIGHT is 2127672 +``` + +Now, let's obtain the authentication token of your light node using the following command: + +::: code-group + +```bash [Arabica Devnet] +AUTH_TOKEN=$(celestia light auth write --p2p.network arabica) +echo -e "\n Your DA AUTH_TOKEN is $AUTH_TOKEN \n" +``` + +```bash [Mocha Testnet] +AUTH_TOKEN=$(celestia light auth write --p2p.network mocha) +echo -e "\n Your DA AUTH_TOKEN is $AUTH_TOKEN \n" +``` + +```bash [Mainnet Beta] +AUTH_TOKEN=$(celestia light auth write) +echo -e "\n Your DA AUTH_TOKEN is $AUTH_TOKEN \n" +``` + +::: + +The output of the command above will look similar to this: + +```bash + Your DA AUTH_TOKEN is eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJBbGxvdyI6WyJwdWJsaWMiLCJyZWFkIiwid3JpdGUiXX0.cSrJjpfUdTNFtzGho69V0D_8kyECn9Mzv8ghJSpKRDE +``` + +Next, let's set up the namespace to be used for posting data on Celestia: + +```bash +DA_NAMESPACE=00000000000000000000000000000000000000000008e5f679bf7116cb +``` + +:::tip +`00000000000000000000000000000000000000000008e5f679bf7116cb` is a default namespace for Mocha testnet. You can set your own by using a command similar to this (or, you could get creative 😎): + +```bash +openssl rand -hex 10 +``` + +Replace the last 20 characters (10 bytes) in `00000000000000000000000000000000000000000008e5f679bf7116cb` with the newly generated 10 bytes. + +[Learn more about namespaces](https://docs.celestia.org/tutorials/node-tutorial#namespaces). +::: + +Lastly, set your DA address for your light node, which by default runs at +port 26658: + +```bash +DA_ADDRESS=http://localhost:26658 +``` + +## 🔥 Running your chain connected to Celestia light node + +Finally, let's initiate the chain node with all the flags: + +```bash +gmd start \ + --evolve.node.aggregator \ + --evolve.da.auth_token $AUTH_TOKEN \ + --evolve.da.namespace $DA_NAMESPACE \ + --evolve.da.start_height $DA_BLOCK_HEIGHT \ + --evolve.da.address $DA_ADDRESS +``` + +Now, the chain is running and posting blocks (aggregated in batches) to Celestia. You can view your chain by using your namespace or account on one of Celestia's block explorers. + +For example, [here on Celenium for Arabica](https://arabica.celenium.io/). + +Other explorers: + +- [Arabica testnet](https://docs.celestia.org/how-to-guides/arabica-devnet) +- [Mocha testnet](https://docs.celestia.org/how-to-guides/mocha-testnet) +- [Mainnet Beta](https://docs.celestia.org/how-to-guides/mainnet) + +## 🎉 Next steps + +Congratulations! You've built a local chain that posts data to Celestia's DA layer. Well done! Now, go forth and build something great! Good luck! diff --git a/docs/guides/da/local-da.md b/docs/guides/da/local-da.md new file mode 100644 index 0000000000..a6aab4c9ab --- /dev/null +++ b/docs/guides/da/local-da.md @@ -0,0 +1,56 @@ +# Using Local DA + + + + +## Introduction {#introduction} + +This tutorial serves as a comprehensive guide for using the [local-da](https://github.com/evstack/ev-node/tree/main/da/cmd/local-da) with your chain. + +Before proceeding, ensure that you have completed the [build a chain](/guides/gm-world.md) tutorial, which covers setting-up, building and running your chain. + +## Setting Up a Local DA Network + +To set up a local DA network node on your machine, run the following script to install and start the local DA node: + +```bash-vue +curl -sSL https://ev.xyz/install-local-da.sh | bash -s {{constants.localDALatestTag}} +``` + +This script will build and run the node, which will then listen on port `7980`. + +## Configuring your chain to connect to the local DA network + +To connect your chain to the local DA network, you need to pass the `--evolve.da.address` flag with the local DA node address. + +## Run your chain + +Start your chain node with the following command, ensuring to include the DA address flag: + +::: code-group + +```sh [Quick Start] +{BINARY} start --evolve.da.address http://localhost:7980 +``` + +```sh [gm-world Chain] +{BINARY} start \ + --evolve.node.aggregator \ + --evolve.da.address http://localhost:7980 \ +``` + +::: + +You should see the following log message indicating that your chain is connected to the local DA network: + +```shell +11:07AM INF NewLocalDA: initialized LocalDA module=local-da +11:07AM INF Listening on host=localhost maxBlobSize=1974272 module=da port=7980 +11:07AM INF server started listening on=localhost:7980 module=da +``` + +## Summary + +By following these steps, you will set up a local DA network node and configure your chain to post data to it. This setup is useful for testing and development in a controlled environment. You can find more information on running the local-da binary [here](https://github.com/evstack/ev-node/blob/main/da/cmd/local-da/README.md) diff --git a/docs/guides/deploy-overview.md b/docs/guides/deploy-overview.md new file mode 100644 index 0000000000..26b4fb4953 --- /dev/null +++ b/docs/guides/deploy-overview.md @@ -0,0 +1,19 @@ +--- +description: This page provides an overview of some common ways to deploy chains. +--- + +# Deploying Your Chain + +One of the benefits of building chains with Evolve is the flexibility you have as a developer to choose things like the DA layer, the settlement scheme, and the execution environment. + +The challenge that comes with this flexibility is that there are more services that now need to be deployed and managed while running your chain. + +In the tutorials so far, you've seen various helper scripts used to make things easier. While great for tutorials, there are better ways to deploy and manage chains than using various bash scripts. + +In this section, you'll see a few examples of how you can deploy your chain environment with all your services running in a more production-ready way. + +:::warning Disclaimer +These examples are for educational purposes only. Before deploying your chain for production use you should fully understand the services you are deploying and your choice in deployment method. +::: + +* [Deploy with Docker Compose](/guides/deploy/local.md) diff --git a/docs/guides/deploy/local.md b/docs/guides/deploy/local.md new file mode 100644 index 0000000000..ea0c7ba13a --- /dev/null +++ b/docs/guides/deploy/local.md @@ -0,0 +1,237 @@ +# 🏠 Local + +This tutorial is going to show you how to deploy the [gm-world chain](/guides/gm-world.md) using Docker Compose. + +You can learn more about Docker Compose [here](https://docs.docker.com/compose/). + + + + +:::tip + +::: + + +## 💻 Pre-requisites {#prerequisites} + +Make sure you have your gm-world chain ready by completing [the Build your chain tutorial](/guides/gm-world.md). + +## 🛠️ Dependencies {#dependencies} + +### 💻 Docker Compose {#docker-compose} + +You can [install docker compose here](https://docs.docker.com/compose/install/). + +Once installed, you can verify the installation by running: + +```bash +docker compose version +``` + +```bash +Docker Compose version v2.23.0-desktop.1 +``` + +## 🛠️ Setting up your environment {#setting-up-your-environment} + +In addition to our chain, we need to run a DA. + +We will use the [local-da](https://github.com/evstack/ev-node/tree/main/da/cmd/local-da) for this tutorial and run it with our chain. + +To save time, we can use the local-da Dockerfile: + +* [local-da Dockerfile](https://github.com/evstack/ev-node/blob/main/Dockerfile.da) +This will allow us to focus on how we can run the gm-world chain with Docker Compose. + +### 🐳 Dockerfile {#dockerfile} + +First, we need to create a Dockerfile for our gm-world chain. Create a new file called `Dockerfile.gm` in the root of the `gm` directory and add the following code: + +```dockerfile-vue +# Stage 1: Install ignite CLI and evolve +FROM golang AS base + +# Install dependencies +RUN apt update && \ + apt-get install -y \ + build-essential \ + ca-certificates \ + curl + +RUN curl -sSL https://ev.xyz/install.sh | bash +# Install evolve + +# Install ignite +RUN curl https://get.ignite.com/cli! | bash + +# Set the working directory +WORKDIR /app + +# cache dependencies. +COPY ./go.mod . +COPY ./go.sum . +RUN go mod download + +# Copy all files from the current directory to the container +COPY . . + +# Build the chain +RUN ignite app install -g github.com/ignite/apps/evolve +RUN ignite chain build -y +RUN ignite evolve init + +# Stage 2: Set up the runtime environment +FROM debian:bookworm-slim + +# Install jq +RUN apt update && \ + apt-get install -y \ + jq + +# Set the working directory +WORKDIR /root + +# Copy over the evolve binary from the build stage +COPY --from=base /go/bin/gmd /usr/bin + + +# Copy the $HOME/.gm directory from the build stage. +# This directory contains all your chain config. +COPY --from=base /root/.gm /root/.gm + +# Keep the container running after it has been started +# CMD tail -f /dev/null + +ENTRYPOINT ["gmd"] +CMD ["start","--evolve.node.aggregator"] +``` + +This Dockerfile sets up the environment to build the chain and run the gm-world node. It then sets up the runtime environment to run the chain. This allows you as the developer to modify any files, and then simply rebuild the Docker image to run the new chain. + +Build the docker image by running the following command: + +```bash +docker build -t gm-world -f Dockerfile.gm . +``` + +```bash +cd evolve +docker build -t local-da -f Dockerfile.da . +cd .. +``` + +You can then see the built image by running: + +```bash +docker images +``` + +You should see the following output: + +```bash +REPOSITORY TAG IMAGE ID CREATED SIZE +gm-world latest 5d3533c1ea1c 8 seconds ago 443MB +``` + +### 🐳 Docker Compose file {#docker-compose-file} + +Next we need to create our `compose.yaml` file for docker compose to use. + +In the root of the `gm` directory, create a new file called `compose.yaml` and add the following code: + +```yml-vue +services: + # Define the gm-world chain service + gm-world: + # Set the name of the docker container for ease of use + container_name: gm-world + # Use the image we just built + image: gm-world + # Used for networking between the two services + network_mode: host + # The command config is used for launching the chain once the Docker container is running + command: + [ + "start", + "--evolve.node.aggregator", + "--evolve.da.address", + "http://0.0.0.0:7980", + ] + # Ensures the local-da service is up and running before starting the chain + depends_on: + - local-da + + # Define the local DA service + local-da: + # Use the published image from evolve + image: local-da + # Set the name of the docker container for ease of use + container_name: local-da + # Publish the ports to connect + ports: + - "7980:7980" + +``` + +We now have all we need to run the gm-world chain and connect to a local DA node. + +### 🚀 Run gm-world chain {#run-gm-world-chain} + +Run your gm-world chain by running the following command: + +```bash +docker compose up +``` + +You'll see logs of your chain being output. + +Congratulations! You have successfully run the gm-world chain with Docker Compose. + +## 🚀 Interacting with the chain {#interacting-with-the-chain} + +Since we are using docker images, we can interact with the chain by entering the docker container. + +You can see the docker containers running with the gm-world chain and the local DA node by running the following command: + +```bash +docker ps +``` + +You should see output like the following: + +```bash +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +d50c7f2fffde local-da "local-da -listen-all" 10 seconds ago Up 9 seconds 0.0.0.0:7980->7980/tcp local-da +b9d5e80e81fb gm-world "gmd start --evolve…" 27 minutes ago Up 9 seconds gm-world +``` + +We can see the gm-world chain running in container `gm-world` and the local DA network running in container `local-da`. + +Since our chain is running in a docker container, we want to enter the docker container to interact with it via the command `gmd`. We can do this by running: + +```bash +docker exec -it gm-world sh +``` + +Now that you are in the docker container, you can interact with the chain using the `gmd` command and the example you used in the [gm-world tutorial](/guides/gm-world.md). + +Once you are done interacting with your chain, you can exit out of your docker container with: + +```bash +exit +``` + +Then you can shut down your chain environment by running `CRTL+C` in your terminal. + +If you want to stop the docker containers without shutting down your terminal, you can run: + +```bash +docker compose down +``` + +## 🎉 Next steps + +Congratulations again! You now know how to run your chain with docker compose and interact with it using the `gmd` command in the docker container. diff --git a/docs/guides/deploy/overview.md b/docs/guides/deploy/overview.md new file mode 100644 index 0000000000..ab7f7095d7 --- /dev/null +++ b/docs/guides/deploy/overview.md @@ -0,0 +1,50 @@ +--- +description: This page provides an overview of some common ways to deploy chains. +--- + +# 🚀 Deploying Your Chain + +One of the benefits of building chains with Evolve is the flexibility you have as a developer to choose things like the DA layer, the settlement scheme, and the execution environment. + +You can learn more about Evolve architecture [here](/learn/specs/overview.md). + +The challenge that comes with this flexibility is that there are more services that now need to be deployed and managed while running your chain. + +In the tutorials so far, you've seen various helper scripts used to make things easier. While great for tutorials, there are better ways to deploy and manage chains than using various bash scripts. + +## 🏗️ Deployment Scales + +Depending on your needs and the stage of your chain development, there are different deployment approaches you can take: + +### 🏠 Local Development + +For development and testing purposes, you can deploy your chain locally using containerized environments. This approach provides: + +- Quick iteration and testing +- No external dependencies +- Full control over the environment +- Cost-effective development + +### 🌐 Testnet Deployment + +When you're ready to test with real network conditions, you can deploy to testnet environments. This includes: + +- Integration with testnet DA networks +- Real network latency and conditions +- Multi-node testing scenarios +- Pre-production validation + +## 📚 Available Deployment Guides + +Choose the deployment approach that matches your current needs: + +- [🏠 Local Development with Docker Compose](./local.md) - Deploy locally for development and testing +- [🌐 Testnet Deployment](./testnet.md) - Deploy on testnet with external DA networks + +:::warning Disclaimer +These examples are for educational purposes only. Before deploying your chain for production use you should fully understand the services you are deploying and your choice in deployment method. +::: + +## 🎉 Next Steps + +For production mainnet deployments, consider additional requirements such as monitoring, security audits, infrastructure hardening, and operational procedures that go beyond the scope of these tutorials. diff --git a/docs/guides/deploy/testnet.md b/docs/guides/deploy/testnet.md new file mode 100644 index 0000000000..edcb61f7e1 --- /dev/null +++ b/docs/guides/deploy/testnet.md @@ -0,0 +1,288 @@ +# 🚀 Evolve EVM Deployment Guide + +This tutorial is going to show you how to deploy a Evolve testnet, focusing on the architecture choices and components that make up a complete EVM-based chain deployment. + +You can learn more about Evolve EVM architecture [here](/learn/execution.md). + + + + +:::tip + +::: + + +## 🏗️ Architecture Overview + +The following diagram illustrates the complete deployment architecture with component interactions: + +```mermaid +graph TB + subgraph "Sequencer Stack" + SEQ_RETH[RETH Service] + SEQ_EVOLVE[EVOLVE Service
--aggregator=true] + SEQ_RETH <--> SEQ_EVOLVE + end + + subgraph "Full Node Stack 1" + FN1_RETH[RETH Service] + FN1_EVOLVE[EVOLVE Service
--aggregator=false] + FN1_RETH <--> FN1_EVOLVE + end + + subgraph "Full Node Stack 2" + FN2_RETH[RETH Service] + FN2_EVOLVE[EVOLVE Service
--aggregator=false] + FN2_RETH <--> FN2_EVOLVE + end + + subgraph "Full Node Stack 3" + FN3_RETH[RETH Service] + FN3_EVOLVE[EVOLVE Service
--aggregator=false] + FN3_RETH <--> FN3_EVOLVE + end + + subgraph "Celestia DA Stack" + CELESTIA_APP[Celestia-App
Consensus Layer] + CELESTIA_NODE[Celestia-Node
DA Sampling & API] + CELESTIA_APP <--> CELESTIA_NODE + end + + %% P2P connections between Evolve nodes + SEQ_EVOLVE <--> FN1_EVOLVE + SEQ_EVOLVE <--> FN2_EVOLVE + SEQ_EVOLVE <--> FN3_EVOLVE + FN1_EVOLVE <--> FN2_EVOLVE + FN2_EVOLVE <--> FN3_EVOLVE + FN1_EVOLVE <--> FN3_EVOLVE + + %% DA connections + SEQ_EVOLVE -->|Post Blobs
Auth Token| CELESTIA_NODE + FN1_EVOLVE -->|Retrieve Blobs
Auth Token| CELESTIA_NODE + FN2_EVOLVE -->|Retrieve Blobs
Auth Token| CELESTIA_NODE + FN3_EVOLVE -->|Retrieve Blobs
Auth Token| CELESTIA_NODE + + %% User interactions + USERS[Users/Applications] --> FN1_RETH + USERS --> FN2_RETH + USERS --> FN3_RETH + + classDef sequencer fill:#e1f5fe + classDef fullnode fill:#f3e5f5 + classDef celestia fill:#fff3e0 + classDef user fill:#e8f5e8 + + class SEQ_RETH,SEQ_EVOLVE sequencer + class FN1_RETH,FN1_EVOLVE,FN2_RETH,FN2_EVOLVE,FN3_RETH,FN3_EVOLVE fullnode + class CELESTIA_APP,CELESTIA_NODE celestia + class USERS user +``` + +**Key Interactions:** +- **Engine API**: RETH ↔ EVOLVE communication within each stack +- **P2P Network**: EVOLVE nodes sync blocks and share chain state +- **Data Availability**: Sequencer posts blobs, full nodes retrieve blobs from Celestia +- **User Access**: Applications connect to full node RETH services for JSON-RPC access + +## 💻 Pre-requisites {#prerequisites} + +Make sure you understand the sequencing topology you want to use by reading the [Sequencing Overview](/learn/sequencing/overview.md). + +## 🛠️ Dependencies {#dependencies} + +### 🔄 Choosing Your Sequencing Topology {#choosing-sequencing-topology} + +First, you need to choose a sequencing topology for your Evolve EVM chain. The sequencing topology determines how transactions are ordered and blocks are produced in your chain. + +Currently, Evolve supports one sequencing implementation: + +### 🔄 Single Sequencer +- **Description**: The simplest sequencing architecture where one node is responsible for ordering transactions and producing blocks +- **Use Cases**: Development, testing, and production deployments requiring simplicity and low latency +- **Advantages**: Easy setup, fast block production, independence from DA block time +- **Requirements**: One sequencer node, multiple optional full nodes + +For detailed information about sequencing topologies, see the [Sequencing Overview](/learn/sequencing/overview.md) and [Single Sequencer](/learn/sequencing/single.md) documentation. + +## 🏗️ Deployment Architecture {#deployment-architecture} + +### 🔄 Single Sequencer Topology + +In a single sequencer deployment, you will run: + +1. **One Sequencer Node** (Required) + - Handles transaction ordering and block production + - Posts data to the Data Availability layer + - Serves as the primary source of truth for the chain + +2. **Multiple Full Nodes** (Optional, but recommended) + - Sync blocks from the sequencer + - Provide redundancy and decentralization + - Can serve user queries and transactions + - Scale horizontally based on demand + +## 🛠️ Setting up your environment {#setting-up-your-environment} + +In addition to choosing your sequencing topology, we need to understand the components that make up your deployment. + +We will use a combination of RETH and EVOLVE services for this tutorial and run them together to create your EVM chain. + +Each node in your Evolve EVM deployment (whether sequencer or full node) consists of two primary services working together: + +### ⚡ RETH Service +- **Purpose**: Provides the Ethereum Virtual Machine (EVM) execution environment +- **Technology**: Rust-based Ethereum client (Reth) that handles transaction execution +- **Responsibilities**: + - Processing EVM transactions + - Maintaining the EVM state + - Providing Ethereum JSON-RPC API endpoints + - Managing the execution layer consensus + +### 🔗 EVOLVE Service +- **Purpose**: Handles chain-specific functionality and consensus +- **Technology**: Evolve node implementation +- **Responsibilities**: + - Block production and validation + - Data availability integration + - P2P networking between chain nodes + - Chain consensus mechanisms + - Communication with the execution layer (RETH) + +### 🔄 Service Interaction + +The two services work together through well-defined interfaces: + +1. **Engine API**: Evolve communicates with RETH using the Engine API (typically on port 8551) +2. **JWT Authentication**: Secure communication between services using shared JWT secrets +3. **Block Coordination**: Evolve orchestrates block production while RETH executes transactions + +## ⚙️ Node Configurations {#node-configurations} + +### 🎯 Sequencer Node Configuration +The single sequencer node runs both RETH and EVOLVE services with specific settings: +- **RETH**: Configured to accept blocks from the Evolve sequencer +- **EVOLVE**: Configured with `--evolve.node.aggregator=true` to enable block production +- **Role**: Produces blocks, orders transactions, posts to DA layer + +### 📡 Full Node Configuration +Each full node also runs both RETH and EVOLVE services but in sync mode: +- **RETH**: Configured to process blocks received from the network +- **EVOLVE**: Configured with `--evolve.node.aggregator=false` to sync from the sequencer +- **Role**: Syncs blocks, serves queries, provides redundancy + +### 🔑 Key Integration Points + +All nodes require: +- Shared JWT secret for Engine API authentication +- Matching genesis configuration between EVOLVE nodes +- Proper network configuration for service communication +- Coordinated startup sequence (typically RETH first, then EVOLVE) + +### ⏰ Block Time Configuration + +You can customize timing parameters for your chain. While there are many configuration arguments available for the Evolve binary, two important timing-related flags are: + +#### 🎯 Sequencer Block Time +- **Flag**: `--evolve.node.block_time` +- **Default**: 1s (1 block per second) +- **Purpose**: Controls how frequently the sequencer produces new blocks +- **Customization**: Can be adjusted based on throughput requirements and latency preferences + +#### 📊 Data Availability Block Time +- **Flag**: `--evolve.da.block_time` +- **Default**: 6s +- **Purpose**: Controls how frequently blobs are posted to the Celestia chain +- **Function**: Each 6 seconds (by default), batched block data is submitted to Celestia for data availability + +## 🌌 Data Availability Layer: Celestia {#celestia-da} + +Your Evolve EVM chain connects to Celestia as the Data Availability (DA) layer. The Evolve EVM Celestia DA stack consists of two key services: + +### 🏛️ Celestia-App Service +- **Purpose**: Provides the consensus layer for the Celestia network +- **Responsibilities**: + - Processing and ordering transactions on the Celestia network + - Maintaining the canonical state of the DA layer + - Participating in Tendermint consensus + +### 🌐 Celestia-Node Service +- **Purpose**: Provides data availability sampling and networking +- **Responsibilities**: + - Data availability sampling (DAS) to verify data availability + - P2P networking for block and data propagation + - Light client functionality for resource-constrained environments + - API endpoints for chains to submit and retrieve data + +### 🔗 Celestia Integration + +Both sequencer and full node Evolve services need to communicate with the celestia-node service, but for different purposes: + +#### 📤 Sequencer Node Communication +- **Purpose**: Batch posting of block data (blobs) to Celestia +- **Operation**: The sequencer Evolve service submits batched block data to Celestia via the celestia-node API +- **Frequency**: Occurs regularly as new blocks are produced and need to be made available + +#### 📥 Full Node Communication +- **Purpose**: Retrieving block data (blobs) from Celestia +- **Operation**: Full node Evolve services query and download historical block data via the celestia-node API +- **Frequency**: Occurs during initial sync and ongoing block validation + +#### 🔑 Common Integration Points +1. **Authentication**: Evolve requires an auth token generated by the celestia-node so that Evolve can send transactions on its behalf. Both sequencer and full node types use these JWT tokens for secure communication with celestia-node +2. **Namespace Isolation**: Data is organized using Celestia namespaces +3. **API Endpoints**: Both sequencer and full nodes use the same celestia-node API interface +4. **Network Configuration**: All nodes must be configured to connect to the same Celestia network + +### 🛠️ Deployment Considerations + +When deploying with Celestia DA: +- **Light Node**: Most chains run a celestia-node in light mode for cost efficiency +- **Network Selection**: Choose between Arabica (devnet), Mocha (testnet), or Mainnet Beta +- **Funding**: Ensure your celestia-node wallet has sufficient TIA tokens for data submission + +We now have all we need to understand the components for deploying a Evolve EVM chain. + +### 🚀 Run your Evolve EVM chain {#run-evolve-evm-chain} + +A complete Evolve EVM chain deployment consists of: + +1. **One Sequencer Node**: RETH + EVOLVE (aggregator mode) +2. **N Full Nodes**: RETH + EVOLVE (sync mode) - scale as needed +3. **Celestia Connection**: celestia-node service for data availability + +You can deploy your chain by running the sequencer and full nodes with the proper configuration. + +Congratulations! You have successfully understood how to deploy a Evolve EVM chain. + +## 🐳 Simplified Deployment with Docker Compose {#docker-compose-deployment} + +The deployment of sequencer and full nodes requires running multiple processes and providing specific variables so they can effectively interact with each other. Managing these configurations manually can be complex and error-prone, especially when coordinating JWT secrets, genesis configurations, network settings, and service dependencies across multiple node stacks. + +To save time, we can use ready-to-use Docker Compose stacks that can be customized based on specific needs. These pre-configured stacks handle the complexity of service orchestration, environment variable management, and inter-service communication automatically. + +To make this deployment process easy and painless for node operators, you can use the example implementation available at: [https://github.com/evstack/ev-toolbox/tree/main/ev-stacks](https://github.com/evstack/ev-toolbox/tree/main/ev-stacks/) + +This solution provides: +- Pre-configured Docker Compose files for sequencer and full node deployments +- Automated handling of JWT secrets and genesis file distribution +- Simplified configuration through environment variables +- Easy scaling of full node instances +- Integrated Celestia node configuration + +:::warning +This deployment approach is suitable for testnets and development environments, but is not suitable for production-grade mainnet deployments, which require additional security considerations, monitoring, backup strategies, and infrastructure hardening. +::: + +## 🎉 Next steps + +Congratulations again! You now know how to deploy Evolve EVM chains and understand the architecture and components needed. + +For detailed setup instructions, see: +- [Single Sequencer Setup Guide](/guides/evm/single.md) - Step-by-step deployment instructions +- [RETH Backup Guide](/guides/evm/reth-backup.md) - Data protection and backup procedures +- [Celestia DA Guide](/guides/da/celestia-da.md) - Connecting to Celestia networks + +You can also learn more about local deployments in our [Docker Compose guide](/guides/deploy/local.md). diff --git a/docs/guides/evm/reth-backup.md b/docs/guides/evm/reth-backup.md new file mode 100644 index 0000000000..5a12e4c5ff --- /dev/null +++ b/docs/guides/evm/reth-backup.md @@ -0,0 +1,239 @@ +# Evolve EVM reth State Backup Guide + +## Introduction + +This guide covers how to backup the reth state of a Evolve EVM based blockchain. This implementation provides a production-ready approach to data protection. + +## Prerequisites + +Before starting, ensure you have: + +- A running Evolve full node - Follow the [Evolve Full Node Setup Guide](https://ev.xyz/guides/full-node) to set up your node +- Zstandard (zstd) compression tool installed +- jq JSON processor installed +- Administrative access to the Docker host +- Sufficient disk space for backups (at least 2x the current volume size) +- Access to remote backup storage (optional but recommended) +- Basic understanding of Docker volumes + +## Installing Dependencies + +For Ubuntu/Debian-based Linux distributions, install the required dependencies: +```bash +# Update package list +sudo apt update + +# Install required tools +sudo apt install -y zstd jq + +# Verify installations +zstd --version +jq --version +``` + +## Key Component to Backup + +Reth datadir : contains the entire EVM state and node data. + +## Performing manual backup + +### 1. Verify Node Synchronization + +```bash +# Check Evolve node status +curl -sX POST \ + -H "Content-Type: application/json" \ + -H "Connect-Protocol-Version: 1" \ + -d "{}" \ + http://:/evolve.v1.HealthService/Livez + +# Verify reth sync status +curl -sX POST \ + -H "Content-Type: application/json" \ + -d '{"jsonrpc":"2.0","method":"eth_syncing","params":[],"id":1}' \ + http://: + +# Expected response for a fully synced node: +# {"jsonrpc":"2.0","id":1,"result":false} +``` + +### 2. Stop Services Gracefully + +You will need to stop both evolve and reth-evolve on the fullnode stack, according to your setup. + +Example for docker-compose based setup: +```bash +# Stop services in correct order +docker compose stop fullnode +docker compose stop reth-evolve + +# Verify all containers are stopped +docker compose ps +``` + +### 3. Create Backup + +```bash +# Create backup directory +# Create backup directory +# IMPORTANT: Set your backup base directory and reth-evolve data directory paths +BACKUP_BASE_DIR="/path/to/backups" +RETH_EVOLVE_DATADIR="/path/to/reth-evolve/datadir" +mkdir -p "${BACKUP_BASE_DIR}" + +# Set backup timestamp +BACKUP_DATE=$(date +%Y%m%d_%H%M%S) + +# Backup reth-evolve datadir using zstandard compression +tar cf - -C "${RETH_EVOLVE_DATADIR}" . | zstd -3 > "${BACKUP_BASE_DIR}/reth_state_${BACKUP_DATE}.tar.zst" + +# Generate checksum +sha256sum "${BACKUP_BASE_DIR}/reth_state_${BACKUP_DATE}.tar.zst" > "${BACKUP_BASE_DIR}/reth_state_${BACKUP_DATE}.tar.zst.sha256" +``` + +### 4. Restart services + +You will need to restart both evolve and reth-evolve on the fullnode stack, according to your setup. + +Example for docker-compose based setup: +```bash +# Start services +docker compose up -d + +# Monitor startup +docker compose logs -f +``` + +## Automated backup + +### 1. Create the Backup Script + +```bash +sudo nano /usr/local/bin/evolve-backup.sh +``` +Add the following content + +```bash +#!/bin/bash +# Reth-Evolve Backup Script with Zstandard Compression + +set -euo pipefail + +# Configuration +RETH_EVOLVE_DATADIR="" # IMPORTANT: Set this to your reth-evolve data directory path +BACKUP_BASE_DIR="${BACKUP_BASE_DIR:-/backup/evolve}" +REMOTE_BACKUP="${REMOTE_BACKUP:-backup-server:/backups/evolve}" +RETENTION_DAYS="${RETENTION_DAYS:-7}" +COMPOSE_FILE="${COMPOSE_FILE:-docker-compose.yml}" +ZSTD_LEVEL="${ZSTD_LEVEL:-3}" +ZSTD_THREADS="${ZSTD_THREADS:-0}" # 0 = auto-detect +FULLNODE_IP="${FULLNODE_IP:-localhost}" +FULLNODE_RPC_PORT="${FULLNODE_RPC_PORT:-7331}" +FULLNODE_RETH_IP="${FULLNODE_RETH_IP:-localhost}" +FULLNODE_RETH_PORT="${FULLNODE_RETH_PORT:-8545}" + +# Functions +log() { + echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" +} + +check_sync_status() { + # Check Evolve node health + curl -fsX POST \ + -H "Content-Type: application/json" \ + -H "Connect-Protocol-Version: 1" \ + -d "{}" \ + "http://${FULLNODE_IP}:${FULLNODE_RPC_PORT}/evolve.v1.HealthService/Livez" > /dev/null + + # Check reth sync status + local sync_status=$(curl -sX POST \ + -H "Content-Type: application/json" \ + -d '{"jsonrpc":"2.0","method":"eth_syncing","params":[],"id":1}' \ + http://${FULLNODE_RETH_IP}:${FULLNODE_RETH_PORT} | jq -r '.result') + + if [ "$sync_status" != "false" ]; then + log "WARNING: Node is still syncing. Backup may be incomplete." + fi +} + +# Main backup process +main() { + log "Starting Evolve backup process" + + # Setup + BACKUP_DATE=$(date +%Y%m%d_%H%M%S) + BACKUP_DIR="${BACKUP_BASE_DIR}" + + # Create backup directory + mkdir -p "${BACKUP_DIR}" + + # Check sync status + check_sync_status + + # Stop services + log "Stopping Evolve services" + docker compose -f ${COMPOSE_FILE} stop fullnode + docker compose -f ${COMPOSE_FILE} stop reth-evolve + + # Backup reth state using zstandard compression + log "Backing up reth state with zstandard compression" + tar cf - -C ${RETH_EVOLVE_DATADIR} . | zstd -${ZSTD_LEVEL} -T${ZSTD_THREADS} > "${BACKUP_DIR}/reth_state_${BACKUP_DATE}.tar.zst" + + # Generate checksum + sha256sum "${BACKUP_DIR}/reth_state_${BACKUP_DATE}.tar.zst" > "${BACKUP_DIR}/reth_state_${BACKUP_DATE}.tar.zst.sha256" + + # Transfer to remote storage + if [ -n "${REMOTE_BACKUP:-}" ]; then + log "Transferring backup to remote storage" + rsync -avz "${BACKUP_DIR}/reth_state_${BACKUP_DATE}.tar.zst*" "${REMOTE_BACKUP}/" || log "WARNING: Remote transfer failed" + fi + + # Restart services + log "Restarting services" + docker compose -f ${COMPOSE_FILE} up -d + + # Cleanup old backups + log "Cleaning up old backups" + find "${BACKUP_BASE_DIR}" -name "reth_state_*.tar.zst" -mtime +${RETENTION_DAYS} -delete + find "${BACKUP_BASE_DIR}" -name "reth_state_*.tar.zst.sha256" -mtime +${RETENTION_DAYS} -delete + + log "Backup completed successfully" +} + +# Run backup +main "$@" +``` + +### 2. Make Script Executable' + +```bash +sudo chmod +x /usr/local/bin/evolve-backup.sh +``` + +### 3. Schedule Automated Backups + +```bash +# Edit crontab +sudo crontab -e + +# Add daily backup at 2 AM +0 2 * * * /usr/local/bin/evolve-backup.sh >> /var/log/evolve-backup.log 2>&1 +``` + +## Best practices + +### Backup Strategy + +1. Schedule regular backups - Daily backups during low-activity periods +2. Implement retention policies - Keep x days of local backups, y days remote +3. Test restoration procedures - Monthly restoration drills in test environment +4. Monitor backup jobs - Set up alerts for failed backups +5. Use appropriate compression levels - Balance between compression ratio and speed + +### Zstandard Compression Levels + +| Level | Speed | Compression Ratio | Use Case | +|-------|---------|-------------------|---------------------| +| 3 | Default | Balanced | Standard backups | +| 9 | Slower | Better | Long-term archives | +| 19 | Slowest | Best | Maximum compression | diff --git a/docs/guides/evm/single.md b/docs/guides/evm/single.md new file mode 100644 index 0000000000..147b0fda1d --- /dev/null +++ b/docs/guides/evm/single.md @@ -0,0 +1,161 @@ +# Evolve EVM Single Sequencer Setup Guide + +## Introduction + +This guide covers how to set up and run the Single Sequencer implementation of Evolve EVM chains. This implementation provides a centralized approach to transaction sequencing while using EVM as the execution layer. + +## Prerequisites + +Before starting, ensure you have: + +- Go 1.20 or later +- Docker and Docker Compose +- Access to the ev-node and ev-reth repositories +- Git + +## Setting Up the Environment + +### 1. Clone the Evolve Repository + +```bash +git clone --depth 1 --branch {{constants.evolveLatestTag}} https://github.com/evstack/ev-node.git +cd evolve +``` + +### 2. Build the Evolve EVM Single Sequencer Implementation + +```bash +make build-evm-single +make build-da +``` + +This will create the following binaries in the `build` directory: + +- `evm-single` - Single sequencer implementation +- `local-da` - Local data availability node for testing + +## Setting Up the Data Availability (DA) Layer + +### Start the Local DA Node + +```bash +cd build +./local-da start +``` + +This will start a local DA node on the default port (26658). + +## Setting Up the EVM Layer + +### 1. Clone the ev-node Repository + +```bash +git clone https://github.com/evstack/ev-node.git +cd ev-node +``` + +### 2. Start the EVM Layer Using Docker Compose + +```bash +docker compose up -d +``` + +This will start Reth (Rust Ethereum client) with the appropriate configuration for Evolve. + +### 3. Note the JWT Secret Path + +The JWT secret is typically located at `ev-node/execution/evm/docker/jwttoken/jwt.hex`. You'll need this path for the sequencer configuration. + +## Running the Single Sequencer Implementation + +### 1. Initialize the Sequencer + +```bash +cd build +./evm-single init --evolve.node.aggregator=true --evolve.signer.passphrase secret +``` + +### 2. Start the Sequencer + +```bash +./evm-single start \ + --evm.jwt-secret $(cat /path/to/ev-node/execution/evm/docker/jwttoken/jwt.hex) \ + --evm.genesis-hash 0x0a962a0d163416829894c89cb604ae422323bcdf02d7ea08b94d68d3e026a380 \ + --evolve.node.block_time 1s \ + --evolve.node.aggregator=true \ + --evolve.signer.passphrase secret +``` + +Replace `/path/to/` with the actual path to your ev-node repository. + +## Setting Up a Full Node + +To run a full node alongside your sequencer, follow these steps: + +### 1. Initialize a New Node Directory + +```bash +./evm-single init --home ~/.evolve/evm-single-fullnode +``` + +### 2. Copy the Genesis File + +Copy the genesis file from the sequencer node to the full node: + +```bash +cp ~/.evolve/evm-single/config/genesis.json ~/.evolve/evm-single-fullnode/config/ +``` + +### 3. Get the Sequencer's P2P Address + +Find the sequencer's P2P address in its logs. It will look similar to: + +```bash +INF listening on address=/ip4/127.0.0.1/tcp/26659/p2p/12D3KooWXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +``` + +### 4. Start the Full Node + +```bash +./evm-single start \ + --home ~/.evolve/evm-single-fullnode \ + --evm.jwt-secret $(cat /path/to/ev-node/execution/evm/docker/jwttoken/jwt.hex) \ + --evm.genesis-hash 0x0a962a0d163416829894c89cb604ae422323bcdf02d7ea08b94d68d3e026a380 \ + --evolve.node.block_time 1s \ + --evolve.node.aggregator=false \ + --evolve.p2p.peers @127.0.0.1:26659 +``` + +Replace `` with the actual P2P ID from your sequencer's logs. + +## Verifying Node Operation + +After starting your nodes, you should see logs indicating successful block processing: + +```bash +INF block marked as DA included blockHash=XXXX blockHeight=XX module=BlockManager +``` + +## Configuration Reference + +### Common Flags + +| Flag | Description | +|------|-------------| +| `--evolve.node.aggregator` | Set to true for sequencer mode, false for full node | +| `--evolve.signer.passphrase` | Passphrase for the signer | +| `--evolve.node.block_time` | Block time for the Evolve node | + +### EVM Flags + +| Flag | Description | +|------|-------------| +| `--evm.eth-url` | Ethereum JSON-RPC URL (default `http://localhost:8545`) | +| `--evm.engine-url` | Engine API URL (default `http://localhost:8551`) | +| `--evm.jwt-secret` | JWT secret file path for the Engine API | +| `--evm.genesis-hash` | Genesis block hash of the chain | +| `--evm.fee-recipient` | Address to receive priority fees | + +## Conclusion + +You've now set up and configured the Single Sequencer implementation of Evolve EVM chains. This implementation provides a centralized approach to transaction sequencing while using EVM as the execution layer. diff --git a/docs/guides/execution/cosmwasm.md b/docs/guides/execution/cosmwasm.md new file mode 100644 index 0000000000..77dc1d8a14 --- /dev/null +++ b/docs/guides/execution/cosmwasm.md @@ -0,0 +1,352 @@ +# 🗞️ CosmWasm chain + + + + + +:::tip + +::: + +CosmWasm is a smart contracting platform built for the Cosmos +ecosystem by making use of [WebAssembly](https://webassembly.org) (Wasm) +to build smart contracts for Cosmos-SDK. In this tutorial, we will be +exploring how to integrate CosmWasm with local DA layer using Evolve. + +The smart contract we will use for this tutorial is one provided by +the CosmWasm team for Nameservice purchasing. + +How to write the Rust smart contract for Nameservice is outside the scope of +this tutorial. + +## 💻 CosmWasm dependency {#dependencies} + +As with the [GM Chain](/guides/gm-world.md), we use [kurtosis](https://docs.kurtosis.com/) to help with managing all the services we need to run. You can [install kurtosis here](https://docs.kurtosis.com/install). + +Once installed, you can verify the installation by running: + +```bash +kurtosis version +``` + +```bash +CLI Version: 0.90.1 + +To see the engine version (provided it is running): kurtosis engine status +``` + +## 🚀 Starting your chain {#start-your-chain} + +Now that we have kurtosis installed, we can launch our CosmWasm chain along with the local DA by running the following command: + +```bash +kurtosis run github.com/evolve/cosmwasm@v0.2.0 +``` + +You should see an output like this: + +```bash +INFO[2024-07-02T11:15:43-04:00] Creating a new enclave for Starlark to run inside... +INFO[2024-07-11T11:53:13-04:00] Enclave 'forgotten-fen' created successfully + +Container images used in this run: +> ghcr.io/evolve/local-da:v0.2.1 - remotely downloaded +> ghcr.io/evolve/cosmwasm:v0.1.0 - remotely downloaded + +Adding service with name 'local-da' and image 'ghcr.io/evolve/local-da:v0.2.1' +Service 'local-da' added with service UUID '96d04bc472c9455d88d046128fbdefa6' + +Printing a message +connecting to da layer via http://172.16.0.5:7980 + +Printing a message +Adding CosmWasm service + +Adding service with name 'wasm' and image 'ghcr.io/evolve/cosmwasm:3b5a25b' +Service 'wasm' added with service UUID 'c71b0308616d40ad919ad24c3d14f35b' + +Printing a message +CosmWasm service is available at http://172.16.0.6:36657 + +Starlark code successfully run. No output was returned. + +⭐ us on GitHub - https://github.com/kurtosis-tech/kurtosis +INFO[2024-07-11T11:53:27-04:00] ====================================================== +INFO[2024-07-11T11:53:27-04:00] || Created enclave: forgotten-fen || +INFO[2024-07-11T11:53:27-04:00] ====================================================== +Name: forgotten-fen +UUID: 8cd936e91ada +Status: RUNNING +Creation Time: Thu, 11 Jul 2024 11:53:00 EDT +Flags: + +========================================= Files Artifacts ========================================= +UUID Name + +========================================== User Services ========================================== +UUID Name Ports Status +96d04bc472c9 local-da jsonrpc: 7980/tcp -> http://127.0.0.1:7980 RUNNING +c71b0308616d wasm grpc-addr: 9290/tcp -> http://127.0.0.1:9290 RUNNING + p2p-laddr: 36656/tcp -> http://127.0.0.1:36656 + rpc-laddr: 36657/tcp -> http://127.0.0.1:36657 +``` + +Kurtosis has successfully launched the CosmWasm chain and the local DA network. You can see the services running in docker as well: + +```bash +docker ps +``` + +```bash +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +5bfeda0a871f ghcr.io/evolve/cosmwasm:v0.1.0 "/bin/sh -c 'wasmd s…" About a minute ago Up About a minute 0.0.0.0:9290->9290/tcp, 0.0.0.0:36656-36657->36656-36657/tcp wasm--c71b0308616d40ad919ad24c3d14f35b +782dec73fcf8 ghcr.io/evolve/local-da:v0.2.1 "local-da -listen-all" About a minute ago Up About a minute 0.0.0.0:7980->7980/tcp local-da--96d04bc472c9455d88d046128fbdefa6 +62da89015918 kurtosistech/core:0.90.1 "/bin/sh -c ./api-co…" About a minute ago Up About a minute 0.0.0.0:55500->7443/tcp kurtosis-api--8cd936e91ada45beab50f0d19be8c57f +1eb6366a5e16 fluent/fluent-bit:1.9.7 "/fluent-bit/bin/flu…" About a minute ago Up About a minute 2020/tcp kurtosis-logs-collector--8cd936e91ada45beab50f0d19be8c57f +8bfee95b49ee kurtosistech/engine:0.90.1 "/bin/sh -c ./kurtos…" 39 minutes ago Up 39 minutes 0.0.0.0:8081->8081/tcp, 0.0.0.0:9710-9711->9710-9711/tcp, 0.0.0.0:9779->9779/tcp kurtosis-engine--cee974a1c2b141478c9eb2a9b1e4f87f +d532fc82579f traefik:2.10.6 "/bin/sh -c 'mkdir -…" 39 minutes ago Up 39 minutes 80/tcp, 0.0.0.0:9730-9731->9730-9731/tcp kurtosis-reverse-proxy--cee974a1c2b141478c9eb2a9b1e4f87f +7700c0b72195 timberio/vector:0.31.0-debian "/bin/sh -c 'printf …" 39 minutes ago Up 39 minutes kurtosis-logs-aggregator +``` + +We can see the CosmWasm chain running in container `wasm--c71b0308616d40ad919ad24c3d14f35b` and the local DA network running in container `local-da--96d04bc472c9455d88d046128fbdefa6`. + +Let's hold on to the container name for the CosmWasm chain, as we will need it later. + +```bash +CW=$(docker ps --format '{{.Names}}' | grep wasm) +echo $CW +``` + +You can verify the chain is running by checking the logs: + +```bash +docker logs $CW +``` + +```bash +... +3:55PM INF Creating and publishing block height=137 module=BlockManager +3:55PM INF finalized block block_app_hash=E71622A57B08D28613A34E3D7AD36BF294CF5A88F4CDD5DD18E6FB65C76F7209 height=137 module=BlockManager num_txs_res=0 num_val_updates=0 +3:55PM INF executed block app_hash=E71622A57B08D28613A34E3D7AD36BF294CF5A88F4CDD5DD18E6FB65C76F7209 height=137 module=BlockManager +3:55PM INF indexed block events height=137 module=txindex +3:55PM INF Creating and publishing block height=138 module=BlockManager +3:55PM INF finalized block block_app_hash=E09F4A71E216D85F4CCB9FCBCEE53D82BCA597451C1D4B4FCE0E4081B5FA40E3 height=138 module=BlockManager num_txs_res=0 num_val_updates=0 +3:55PM INF executed block app_hash=E09F4A71E216D85F4CCB9FCBCEE53D82BCA597451C1D4B4FCE0E4081B5FA40E3 height=138 module=BlockManager +... +``` + +Good work so far, we have a Chain node, DA network node, now we can move onto the contract deployment. + +## 📒 Contract deployment on CosmWasm with Evolve {#contract-deployment-on-cosmwasm} + +### 🤖 Compile the smart contract {#compile-smart-contract} + +To compile the smart contract, you can use our docker image. + +First download the image: + +```bash +docker pull ghcr.io/evolve/contract:v0.2.0 +``` + +Then run the container: + +```bash +docker run --rm -d --name cw ghcr.io/evolve/contract:v0.2.0 +``` + +The container is now running and has the pre-built nameservice contract for us. Let's copy it out of the container. + +```bash +docker cp cw:/root/cw-contracts/contracts/nameservice . +``` + +We now have the nameservice contract in the `nameservice` directory. + +### 🏎️ Optimized smart contract {#optimized-smart-contract} + +Because we are deploying the compiled smart contract to `wasmd`, +we want it to be as small as possible. + + +The CosmWasm team provides a tool called `rust-optimizer`, which requires +[Docker](#docker-installation) in order to compile. + + +Run the following command in the `~/nameservice` directory you just copied: + +```bash +sudo docker run --rm -v "$(pwd)":/code \ + --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ + --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ + cosmwasm/rust-optimizer:0.12.6 +``` + +This will place the optimized Wasm bytecode at `artifacts/cw_nameservice.wasm`. + +### 🚀 Contract deployment {#contract-deployment} + +Let's now deploy our smart contract! + +We will need to do this in the docker container that the CosmWasm chain is running. So first let's move the compiled contract to the container: + +```bash +docker cp artifacts/cw_nameservice.wasm $CW:/root/cw_nameservice.wasm +``` + +Now let's jump into the container: + +```bash +docker exec -it $CW sh +``` + +In order to deploy a contract, you can use the command line as described below. +For a better experience and to use Rust code instead of the command line to +deploy/script and test your contracts, you can use cw-orchestrator. + + +```bash +TX_HASH=$(wasmd tx wasm store cw_nameservice.wasm --from localwasm-key --keyring-backend test --chain-id localwasm --gas-prices 0.025uwasm --gas auto --gas-adjustment 1.3 --node http://127.0.0.1:36657 --output json -y | jq -r '.txhash') && echo $TX_HASH +``` + + +This will get you the transaction hash for the smart contract deployment. + +::: danger +If you run into errors with variables on the previous command, +or commands in the remainder of the tutorial, cross-reference +the variables in the command with the variables in the `init.sh` script. +::: + +## 🌟 Contract interaction on CosmWasm {#contract-interaction-on-local-da} + + +In the previous steps, we have stored out contract's tx hash in an +environment variable for later use. + +The following guide will show you how to deploy and interact with a contract using CLI. +For scripting using Rust, you can use cw-orchestrator. + +### 🔎 Contract querying {#contract-querying} + +Now, let's query our transaction hash for its code ID: + +```bash +CODE_ID=$(wasmd query tx --type=hash $TX_HASH --node http://127.0.0.1:36657 --output json | jq -r '.events[-1].attributes[1].value') +echo $CODE_ID +``` + +This will give us back the Code ID of the deployed contract. + +In our case, since it's the first contract deployed on our local network, +the value is `1`. + +Now, we can take a look at the contracts instantiated by this Code ID: + +```bash +wasmd query wasm list-contract-by-code $CODE_ID --node http://127.0.0.1:36657 --output json +``` + +We get the following output: + +```json +{"contracts":[],"pagination":{"next_key":null,"total":"0"}} +``` + +### 📃 Contract instantiation {#contract-instantiation} + +We start instantiating the contract by writing up the following `INIT` message +for nameservice contract. Here, we are specifying that `purchase_price` of a name +is `100uwasm` and `transfer_price` is `999uwasm`. + +```bash +INIT='{"purchase_price":{"amount":"100","denom":"uwasm"},"transfer_price":{"amount":"999","denom":"uwasm"}}' +wasmd tx wasm instantiate $CODE_ID "$INIT" --from localwasm-key --keyring-backend test --label "name service" --chain-id localwasm --gas-prices 0.025uwasm --gas auto --gas-adjustment 1.3 -y --no-admin --node http://127.0.0.1:36657 +``` + +### 📄 Contract interaction {#contract-interaction} + +Now that we instantiated it, we can interact further with the contract: + +```bash +wasmd query wasm list-contract-by-code $CODE_ID --output json --node http://127.0.0.1:36657 +CONTRACT=$(wasmd query wasm list-contract-by-code $CODE_ID --output json --node http://127.0.0.1:36657 | jq -r '.contracts[-1]') +echo $CONTRACT + +wasmd query wasm contract --node http://127.0.0.1:36657 $CONTRACT +wasmd query bank balances --node http://127.0.0.1:36657 $CONTRACT +``` + +This allows us to see the contract address, contract details, and +bank balances. + +Your output will look similar to below: + +```bash +{"contracts":["wasm14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9s0phg4d"],"pagination":{"next_key":null,"total":"0"}} +wasm14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9s0phg4d +address: wasm14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9s0phg4d +contract_info: + admin: "" + code_id: "1" + created: null + creator: wasm1y9ceqvnsnm9xtcdmhrjvv4rslgwfzmrzky2c5z + extension: null + ibc_port_id: "" + label: name service +balances: [] +pagination: + next_key: null + total: "0" +``` + +Now, let's register a name to the contract for our wallet address: + +```bash +REGISTER='{"register":{"name":"fred"}}' +wasmd tx wasm execute $CONTRACT "$REGISTER" --amount 100uwasm --from localwasm-key --chain-id localwasm --gas-prices 0.025uwasm --gas auto --gas-adjustment 1.3 --node http://127.0.0.1:36657 --keyring-backend test -y +``` + +Your output will look similar to below: + +```bash +gas estimate: 167533 +code: 0 +codespace: "" +data: "" +events: [] +gas_used: "0" +gas_wanted: "0" +height: "0" +info: "" +logs: [] +raw_log: '[]' +timestamp: "" +tx: null +txhash: C147257485B72E7FFA5FDB943C94CE951A37817554339586FFD645AD2AA397C3 +``` + +If you try to register the same name again, you'll see an expected error: + +```bash +Error: rpc error: code = Unknown desc = rpc error: code = Unknown desc = failed to execute message; message index: 0: Name has been taken (name fred): execute wasm contract failed [CosmWasm/wasmd/x/wasm/keeper/keeper.go:364] With gas wanted: '0' and gas used: '123809' : unknown request +``` + +Next, query the owner of the name record: + +```bash +NAME_QUERY='{"resolve_record": {"name": "fred"}}' +wasmd query wasm contract-state smart $CONTRACT "$NAME_QUERY" --node http://127.0.0.1:36657 --output json +``` + +You'll see the owner's address in a JSON response: + +```bash +{"data":{"address":"wasm1y9ceqvnsnm9xtcdmhrjvv4rslgwfzmrzky2c5z"}} +``` + +With that, we have instantiated and interacted with the CosmWasm nameservice +smart contract on our local DA network using Evolve! diff --git a/docs/guides/full-node.md b/docs/guides/full-node.md new file mode 100644 index 0000000000..41da99417c --- /dev/null +++ b/docs/guides/full-node.md @@ -0,0 +1,103 @@ +# Chain Full Node Setup Guide + +## Introduction + +This guide covers how to set up a full node to run alongside a sequencer node in a Evolve-based blockchain network. A full node maintains a complete copy of the blockchain and helps validate transactions, improving the network's decentralization and security. + +## Prerequisites + +Before proceeding, ensure that you have completed the [build a chain](/guides/gm-world.md) tutorial, which covers setting-up, building and running your chain. + +Ensure that you have: + +- A local Data Availability (DA) network node running on port `7980`. +- A Evolve sequencer node running and posting blocks to the DA network. + +## Setting Up Your Full Node + +### Initialize Chain Config and Copy Genesis File + +Let's set a terminal variable for the chain ID. + +```bash +CHAIN_ID=gm +``` + +Initialize the chain config for the full node, lets call it `FullNode` and set the chain ID to your chain ID: + +```bash +gmd init FullNode --chain-id $CHAIN_ID --home $HOME/.${CHAIN_ID}_fn +``` + +Copy the genesis file from the sequencer node: + +```bash +cp $HOME/.$CHAIN_ID/config/genesis.json $HOME/.${CHAIN_ID}_fn/config/genesis.json +``` + +### Set Up P2P Connection to Sequencer Node + +Identify the sequencer node's P2P address from its logs. It will look similar to: + +``` +1:55PM INF listening on address=/ip4/127.0.0.1/tcp/7676/p2p/12D3KooWJbD9TQoMSSSUyfhHMmgVY3LqCjxYFz8wQ92Qa6DAqtmh module=p2p +``` + +Create an environment variable with the P2P address: + +```bash +export P2P_ID="12D3KooWJbD9TQoMSSSUyfhHMmgVY3LqCjxYFz8wQ92Qa6DAqtmh" +``` + +### Start the Full Node + +We are now ready to run our full node. If we are running the full node on the same machine as the sequencer, we need to make sure we update the ports to avoid conflicts. + +Make sure to include these flags with your start command: + +```sh + --rpc.laddr tcp://127.0.0.1:46657 \ + --grpc.address 127.0.0.1:9390 \ + --p2p.laddr "0.0.0.0:46656" \ + --api.address tcp://localhost:1318 +``` + +Run your full node with the following command: + +```bash +gmd start \ + --evolve.da.address http://127.0.0.1:7980 \ + --p2p.seeds $P2P_ID@127.0.0.1:7676 \ + --minimum-gas-prices 0stake \ + --rpc.laddr tcp://127.0.0.1:46657 \ + --grpc.address 127.0.0.1:9390 \ + --p2p.laddr "0.0.0.0:46656" \ + --api.address tcp://localhost:1318 \ + --chain_id $CHAIN_ID \ + --home $HOME/.${CHAIN_ID}_fn +``` + +Key points about this command: + +- `chain_id` is generally the `$CHAIN_ID`, which is `gm` in this case. +- The ports and addresses are different from the sequencer node to avoid conflicts. Not everything may be necessary for your setup. +- We use the `P2P_ID` environment variable to set the seed node. + +## Verifying Full Node Operation + +After starting your full node, you should see output similar to: + +``` bash +2:33PM DBG indexed transactions height=1 module=txindex num_txs=0 +2:33PM INF block marked as DA included blockHash=7897885B959F52BF0D772E35F8DA638CF8BBC361C819C3FD3E61DCEF5034D1CC blockHeight=5532 module=BlockManager +``` + +This output indicates that your full node is successfully connecting to the network and processing blocks. + +:::tip +If your chain uses EVM as an execution layer and you see an error like `datadir already used by another process`, it means you have to remove all the state from chain data directory (`/root/.yourchain_fn/data/`) and specify a different data directory for the EVM client. +::: + +## Conclusion + +You've now set up a full node running alongside your Evolve sequencer. diff --git a/docs/guides/gm-world.md b/docs/guides/gm-world.md new file mode 100644 index 0000000000..c0262e037f --- /dev/null +++ b/docs/guides/gm-world.md @@ -0,0 +1,291 @@ +--- +title: GM World tutorial +description: Learn how to build and deploy a CosmWasm-based "gm" (good morning) application using Evolve. +--- + +# GM world chain + +## 🌞 Introduction {#introduction} + +This tutorial will guide you through building a evolve `gm-world` chain (`gm` stands for "good morning") using Evolve. Unlike the [quick start guide](/guides/quick-start.md), this tutorial provides a more practical approach to understanding evolve chain development. + +We will cover: + +- Building and configuring a Cosmos-SDK application-specific chain. +- Posting chain data to a Data Availability (DA) network. +- Executing transactions (the end goal). + +No prior understanding of the build process is required, just that it utilizes the [Cosmos SDK](https://github.com/cosmos/cosmos-sdk) for blockchain applications. + + + + +:::tip + +::: + + +## 🛠️ Dependencies {#dependencies} + +As we move into more advanced use cases, we use [ignite](https://docs.ignite.com/welcome) to help with managing all the services we need to run. You can [install ignite here](https://docs.ignite.com/welcome/install). + +Once installed, you can verify the installation by running: + +```bash +ignite version +``` + +```bash +Ignite CLI version: v29.2.0-dev +Ignite CLI build date: undefined +Ignite CLI source hash: undefined +Ignite CLI config version: v1 +Cosmos SDK version: v0.53.0 +Buf.build version: undefined +Your OS: darwin +Your arch: arm64 +Your go version: go version go1.24.3 darwin/arm64 +``` + +## Generate your App {#generate-your-app} + +```bash +ignite scaffold chain gm --address-prefix gm +cd gm +``` + +Install a specific version of ignite to use evolve + +```bash +ignite app install -g github.com/ignite/apps/evolve +``` + +Install your app locally: + +```bash +make install +``` + +## Add Evolve Features {#add-evolve-features} + +Enhance your blockchain by adding Evolve features. Use the following command: + +```bash +ignite evolve add +``` + +## Build your chain {#build-your-chain} + +Build your chain using the following command: + +```bash +ignite chain build +``` + +This will create a `~/.gm` folder with all the necessary files to run a chain. + +## Initialize Your Blockchain {#initialize-your-blockchain} + +Before starting your blockchain, you need to initialize it with Evolve support. Initialize the blockchain as follows: + +```bash +ignite evolve init +``` + +It will also initialize 2 accounts `alice` and `bob`: + +## 🚀 Starting your chain {#start-your-chain} + +Now that we have our gm app generated and installed, we can launch our GM chain along with the local DA by running the following command: + +First lets start the local DA network: + +```bash +curl -sSL https://ev.xyz/install-local-da.sh | bash -s {{constants.evolveLatestTag}} +``` + +you should see logs like: + +```bash +4:58PM INF NewLocalDA: initialized LocalDA module=local-da +4:58PM INF Listening on host=localhost maxBlobSize=1974272 module=da port=7980 +4:58PM INF server started listening on=localhost:7980 module=da +``` + +After which we can start the app: + +```bash +gmd start --evolve.node.aggregator +``` + +You should see an output like this: + +```bash +2:50PM INF creating new client module=evolve namespace= +2:50PM INF No state found in store, initializing new state module=BlockManager +2:50PM INF Initializing chain chainID=gm genesisTime=2025-06-26T12:50:11Z initialHeight=1 module=evolve +2:50PM INF InitChain chainID=gm initialHeight=1 module=baseapp +2:50PM INF initializing blockchain state from genesis.json module=baseapp +2:50PM INF chain initialized successfully appHash=E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855 module=evolve +2:50PM INF using default mempool ttl MempoolTTL=25 module=BlockManager +2:50PM INF service start impl=EventBus module=events msg="Starting EventBus service" +2:50PM INF service start impl=PubSub module=pubsub msg="Starting PubSub service" +2:50PM INF service start impl=IndexerService module=txindex msg="Starting IndexerService service" +2:50PM INF evolve node run loop launched in background goroutine module=server +2:50PM INF serving HTTP listen address=[::]:26657 module=evolve +2:50PM INF starting P2P client module=evolve +2:50PM INF started RPC server addr=127.0.0.1:7331 module=evolve +2:50PM INF listening on address=/ip4/127.0.0.1/tcp/7676/p2p/12D3KooWPN1jqkgZcuF8UMZEa7nSjoF7zPmGHRrCDVrXrpfTLpfJ module=p2p +2:50PM INF listening on address=/ip4/192.168.0.54/tcp/7676/p2p/12D3KooWPN1jqkgZcuF8UMZEa7nSjoF7zPmGHRrCDVrXrpfTLpfJ module=p2p +2:50PM INF no peers - only listening for connections module=p2p +2:50PM INF working in aggregator mode block time=1s module=evolve +2:50PM INF Reaper started interval=1000 module=Reaper +2:50PM INF using pending block height=1 module=BlockManager +2:50PM INF Executing block height=1 module=evolve num_txs=0 timestamp=2025-06-26T14:50:11+02:00 +2:50PM INF block executed successfully appHash=678DE6BBA6E23B000DC5AC86B60245E6EAC503C5C7085495F3B71B22A762EB19 height=1 module=evolve +2:50PM INF indexed block events height=1 module=txindex +2:50PM INF attempting to start executor (Adapter.Start) module=server +2:50PM INF executor started successfully module=server +2:50PM INF creating empty block height=2 module=BlockManager +2:50PM INF Executing block height=2 module=evolve num_txs=0 timestamp=2025-06-26T14:50:30+02:00 +2:50PM INF starting API server... address=tcp://0.0.0.0:1317 module=api-server +2:50PM INF serve module=api-server msg="Starting RPC HTTP server on [::]:1317" +2:50PM INF starting gRPC server... address=localhost:9090 module=grpc-server +2:50PM INF block executed successfully appHash=0B3973A50C42D0184FB86409FC427BD528A790FA45BA2C9E20FDF14A3628CEC8 height=2 module=evolve +``` + +Ignite has successfully launched the GM chain and the local DA network. The GM chain is running on port `7331` and the local DA network is running on port `7980`. + +Good work so far, we have a Chain node, DA network node, now we can start submitting transactions. + +## 💸 Transactions {#transactions} + +First, list your keys: + +```bash +gmd keys list --keyring-backend test +``` + +You should see an output like the following + +```bash +- address: gm17rpwv7lnk96ka00v93rphhvcqqztpn896q0dxx + name: alice + pubkey: '{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"A5WPM5WzfNIPrGyha/TlHt0okdlzS1O4Gb1d1kU+xuG+"}' + type: local +- address: gm1r2udsh4za7r7sxvzy496qfazvjp04j4zgytve3 + name: bob + pubkey: '{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"A+jOX/CWInFer2IkqgXGo0da9j7Ubq+e1LJWzTMDjwdt"}' + type: local +``` + +For convenience we export two of our keys like this: + +```bash +export ALICE=gm17rpwv7lnk96ka00v93rphhvcqqztpn896q0dxx +export BOB=gm1r2udsh4za7r7sxvzy496qfazvjp04j4zgytve3 +``` + +Now let's submit a transaction that sends coins from one account to another (don't worry about all the flags, for now, we just want to submit transaction from a high-level perspective): + +```bash +gmd tx bank send $BOB $ALICE 42069stake --keyring-backend test --chain-id gm --fees 5000stake +``` + +You'll be prompted to accept the transaction: + +```bash +auth_info: + fee: + amount: [] + gas_limit: "200000" + granter: "" + payer: "" + signer_infos: [] + tip: null +body: + extension_options: [] + memo: "" + messages: + - '@type': /cosmos.bank.v1beta1.MsgSend + amount: + - amount: "42069" + denom: stake + from_address: gm1r2udsh4za7r7sxvzy496qfazvjp04j4zgytve3 + to_address: gm17rpwv7lnk96ka00v93rphhvcqqztpn896q0dxx + non_critical_extension_options: [] + timeout_height: "0" +signatures: [] +confirm transaction before signing and broadcasting [y/N]: // [!code focus] +``` + +Confirm and sign the transaction as prompted. now you see the transaction hash at the output: + +```bash +//... + +txhash: 677CAF6C80B85ACEF6F9EC7906FB3CB021322AAC78B015FA07D5112F2F824BFF +``` + +## ⚖️ Checking Balances {#balances} + +Query balances after the transaction: + +```bash +gmd query bank balances $ALICE +``` + +The receiver’s balance should show an increase. + +```bash +balances: // [!code focus] +- amount: "42069" // [!code focus] + denom: stake +pagination: + next_key: null + total: "0" +``` + +For the sender’s balance: + +```bash +gmd query bank balances $BOB +``` + +Output: + +```bash +balances: // [!code focus] +- amount: "99957931" // [!code focus] + denom: stake +pagination: + next_key: null + total: "0" +``` + + + +## 🎉 Next steps + +Congratulations! You've experienced connecting to a chain from the user side — simple and straightforward. Now, you might consider exploring how to add more application logic to your chain using the Cosmos SDK, as demonstrated in our Wordle App tutorial. diff --git a/docs/guides/metrics.md b/docs/guides/metrics.md new file mode 100644 index 0000000000..4d290e4b5a --- /dev/null +++ b/docs/guides/metrics.md @@ -0,0 +1,79 @@ +# Evolve Metrics Guide + +## How to configure metrics + +Evolve can report and serve Prometheus metrics, which can be consumed by Prometheus collector(s). + +This functionality is disabled by default. + +To enable Prometheus metrics, set `instrumentation.prometheus=true` in your Evolve node's configuration file. + +Metrics will be served under `/metrics` on port 26660 by default. The listening address can be changed using the `instrumentation.prometheus_listen_addr` configuration option. + +## List of available metrics + +You can find the full list of available metrics in the [Technical Specifications](../learn/specs/block-manager.html#metrics). + +## Viewing Metrics + +Once your Evolve node is running with metrics enabled, you can view the metrics by: + +1. Accessing the metrics endpoint directly: + + ```bash + curl http://localhost:26660/metrics + ``` + +2. Configuring Prometheus to scrape these metrics by adding the following to your `prometheus.yml`: + + ```yaml + scrape_configs: + - job_name: evolve + static_configs: + - targets: ['localhost:26660'] + ``` + +3. Using Grafana with Prometheus as a data source to visualize the metrics. + +## Example Prometheus Configuration + +Here's a basic Prometheus configuration to scrape metrics from a Evolve node: + +```yaml +global: + scrape_interval: 15s + evaluation_interval: 15s + +scrape_configs: + - job_name: evolve + static_configs: + - targets: ['localhost:26660'] +``` + +## Troubleshooting + +If you're not seeing metrics: + +1. Ensure metrics are enabled in your configuration with `instrumentation.prometheus=true` +2. Verify the metrics endpoint is accessible: `curl http://localhost:26660/metrics` +3. Check your Prometheus configuration is correctly pointing to your Evolve node +4. Examine the Evolve node logs for any errors related to the metrics server + +## Advanced Configuration + +For more advanced metrics configuration, you can adjust the following settings in your configuration file: + +```yaml +instrumentation: + prometheus: true + prometheus_listen_addr: ":26660" + max_open_connections: 3 + namespace: "evolve" +``` + +These settings allow you to: + +- Enable/disable Prometheus metrics +- Change the listening address for the metrics server +- Limit the maximum number of open connections to the metrics server +- Set a custom namespace for all metrics diff --git a/docs/guides/quick-start.md b/docs/guides/quick-start.md new file mode 100644 index 0000000000..736ffa7ce3 --- /dev/null +++ b/docs/guides/quick-start.md @@ -0,0 +1,102 @@ +--- +description: Quickly start a chain node using the Testapp CLI. +--- + + + +# Quick start guide + +Welcome to Evolve, a chain framework! The easiest way to launch your network node is by using the Testapp CLI. + +## 📦 Install Testapp (CLI) + +To install Evolve, clone the repository and build the binary: + +```bash +# Clone the repository +git clone https://github.com/evolve/ev-node.git +cd ev-node + +# Build the testapp binary +make build + +# Optional: Install to your Go bin directory for system-wide access +make install +``` + +Verify the installation by checking the Evolve version: + +```bash +# If you ran 'make install' +testapp version + +# Or if you only ran 'make build' +./build/testapp version +``` + +A successful installation will display the version number and its associated git commit hash. + +```bash +evolve version: execution/evm/v1.0.0-beta.1 +evolve git sha: cd1970de +``` + +## 🗂️ Initialize a evolve network node + +To initialize a evolve network node, execute the following command: + +```bash +testapp init --evolve.node.aggregator --evolve.signer.passphrase secret +``` + +## 🚀 Run your evolve network node + +Now that we have our testapp generated and installed, we can launch our chain along with the local DA by running the following command: + +First lets start the local DA network: + +```bash +# If you're not already in the ev-node directory +cd ev-node + +# Start the local DA network using the built binary +./build/testapp da start +``` + +You should see logs like: + +```bash +9:22AM INF NewLocalDA: initialized LocalDA component=da +9:22AM INF Listening on component=da host=localhost maxBlobSize=1974272 port=7980 +9:22AM INF server started component=da listening_on=localhost:7980 +``` + +To start a basic evolve network node, execute: + +```bash +testapp start --evolve.signer.passphrase secret +``` + +Upon execution, the CLI will output log entries that provide insights into the node's initialization and operation: + +```bash +9:23AM INF creating new client component=main namespace= +KV Executor HTTP server starting on 127.0.0.1:9090 +9:23AM INF KV executor HTTP server started component=main endpoint=127.0.0.1:9090 +9:23AM INF No state found in store, initializing new state component=BlockManager +9:23AM INF using default mempool ttl MempoolTTL=25 component=BlockManager +9:23AM INF starting P2P client component=main +9:23AM INF started RPC server addr=127.0.0.1:7331 component=main +9:23AM INF listening on address address=/ip4/127.0.0.1/tcp/7676/p2p/12D3KooWRzvJuFoQKhQNfaCZWvJFDY4vrCTocdL6H1GCMzywugnV component=main +9:23AM INF listening on address address=/ip4/172.20.10.14/tcp/7676/p2p/12D3KooWRzvJuFoQKhQNfaCZWvJFDY4vrCTocdL6H1GCMzywugnV component=main +9:23AM INF no peers - only listening for connections component=main +9:23AM INF working in aggregator mode block_time=1000 component=main +9:23AM INF using pending block component=BlockManager height=1 +9:23AM INF Reaper started component=Reaper interval=1000 +``` + +## 🎉 Conclusion + +That's it! Your evolve network node is now up and running. It's incredibly simple to start a blockchain (which is essentially what a chain is) these days using Evolve. Explore further and discover how you can build useful applications on Evolve. Good luck! diff --git a/docs/guides/reset-state.md b/docs/guides/reset-state.md new file mode 100644 index 0000000000..c10193198a --- /dev/null +++ b/docs/guides/reset-state.md @@ -0,0 +1,147 @@ +# How to reset the state of your chain + +This guide will walk you through how you reset the state of your chain. + +:::warning Disclaimer +By definition, resetting the state is deleting your chain's data. Make sure you understand the implications of this prior to completing this guide. +::: + +Some reason you might need to reset the state of your chain are: + +* During testing and development +* During upgrades with breaking changes +* Hardforks + +## Prerequisites + +In order to complete this guide, you will need to have completed either the [quick start tutorial](/guides/quick-start.md) or the [build our chain tutorial](/guides/gm-world.md). + +## Quick Start + +When you run your chain with `testapp start` you will create a `.testapp` directory in your root directory. + +This directory will look like the following. + +```bash +tree $HOME/.testapp + +├── config +│   ├── genesis.json +│   ├── node_key.json +│   ├── evolve.yaml +│   └── signer.json +└── data + ├── cache + │   ├── data + │   │   ├── da_included.gob + │   │   ├── hashes.gob + │   │   ├── items_by_hash.gob + │   │   └── items_by_height.gob + │   └── header + │   ├── da_included.gob + │   ├── hashes.gob + │   ├── items_by_hash.gob + │   └── items_by_height.gob + ├── executor + │   ├── 000001.sst + │   ├── 000002.vlog + │   ├── 000003.vlog + │   ├── 00003.mem + │   ├── DISCARD + │   ├── KEYREGISTRY + │   ├── LOCK + │   └── MANIFEST + └── testapp + ├── 000001.sst + ├── 000002.sst + ├── 000002.vlog + ├── 000003.sst + ├── 000003.vlog + ├── DISCARD + ├── KEYREGISTRY + └── MANIFEST +``` + +To reset the state of the chain, delete the content of the `data` directory. + +Alternatively, you can use this command. + +```bash +testapp unsafe-clean +``` + +When you launch your chain again with `testapp start` your `data` directory will be re-populated and you will see your chain starting at block height 1 again. + +## gm-world + +When you ran your gm-world chain in the [build your chain tutorial](/guides/gm-world.md), it created a `.gm` directory in your `$HOME` directory. + +This directory will look like the following: + +```bash +tree $HOME/.gm + +├── config +│   ├── app.toml +│   ├── client.toml +│   ├── config.toml +│   ├── genesis.json +│   ├── gentx +│   │   └── gentx-418077c64f0cf5824c24487c9cce38241de677cd.json +│   ├── node_key.json +│   ├── priv_validator_key.json +│   └── evolve.yaml +├── data +│   ├── application.db +│   │   ├── 000001.log +│   │   ├── CURRENT +│   │   ├── LOCK +│   │   ├── LOG +│   │   └── MANIFEST-000000 +│   ├── cache +│   │   ├── data +│   │   │   ├── da_included.gob +│   │   │   ├── hashes.gob +│   │   │   ├── items_by_hash.gob +│   │   │   └── items_by_height.gob +│   │   └── header +│   │   ├── da_included.gob +│   │   ├── hashes.gob +│   │   ├── items_by_hash.gob +│   │   └── items_by_height.gob +│   ├── priv_validator_state.json +│   ├── evolve +│   │   ├── 000001.sst +│   │   ├── 000001.vlog +│   │   ├── DISCARD +│   │   ├── KEYREGISTRY +│   │   └── MANIFEST +│   ├── snapshots +│   │   └── metadata.db +│   │   ├── 000001.log +│   │   ├── CURRENT +│   │   ├── LOCK +│   │   ├── LOG +│   │   └── MANIFEST-000000 +│   └── tx_index.db +│   ├── 000001.log +│   ├── CURRENT +│   ├── LOCK +│   ├── LOG +│   └── MANIFEST-000000 +└── keyring-test + ├── 87af99a184613860ee9563be57a9fb4e7b25acb8.address + ├── alice.info + ├── bob.info + └── e24d9eeca2d24193bdd98ed9116ff70f8a2e2b5e.address +``` + +The directories you need to delete to reset your state are in the `data` directory. + +Alternatively, you can run the following command to delete the data directories: + +```bash +gmd comet unsafe-reset-all +``` + +When you launch your chain again with your `gmd start ` command, these data directories will be re-created and you will see your chain starting at block height 1 again. diff --git a/docs/guides/restart-chain.md b/docs/guides/restart-chain.md new file mode 100644 index 0000000000..e655e4750c --- /dev/null +++ b/docs/guides/restart-chain.md @@ -0,0 +1,101 @@ +# 🔄 How to restart your chain + +This guide will teach you how to restart your Evolve chain. + +## Restart chain + +This section covers the case where you need to restart your chain. + +In order to restart your chain, you simply need to run the `d start [...args]` +command for your chain. + +For example, if you ran the [quick start](/guides/quick-start.md) tutorial, you started your chain with: + +```bash +testapp start +``` + +You would have see output similar to: + +```bash +I[2024-10-17|14:52:12.845] Creating and publishing block module=BlockManager height=7 +I[2024-10-17|14:52:12.845] finalized block module=BlockManager height=7 num_txs_res=0 num_val_updates=0 block_app_hash= +I[2024-10-17|14:52:12.845] executed block module=BlockManager height=7 app_hash= +I[2024-10-17|14:52:12.846] indexed block events module=txindex height=7 +``` + +If you need to restart your chain, you can run the same command again: + +```bash +testapp start +``` + +You will see that the block height will continue from where it left off: + +```bash +I[2024-10-17|14:52:13.845] Creating and publishing block module=BlockManager height=8 +I[2024-10-17|14:52:13.845] finalized block module=BlockManager height=8 num_txs_res=0 num_val_updates=0 block_app_hash= +I[2024-10-17|14:52:13.845] executed block module=BlockManager height=8 app_hash= +I[2024-10-17|14:52:13.845] indexed block events module=txindex height=8 +``` + +It is important to include any additional flags that you used when you first started your chain. For example, if you used the `--evolve.da.namespace` flag, you will need to include that flag when restarting your chain to ensure your chain continues to publish blobs to the same namespace. + +## Restart chain after running out of funds + +This section covers the case that the node that +you are using to post blocks to your DA and consensus layer runs out of funds (tokens), +and you need to restart your chain. + +In this example, we're using Celestia's [Mocha testnet](https://docs.celestia.org/how-to-guides/mocha-testnet/) +and running the [quick start](/guides/quick-start.md). In this example, our Celestia DA light node +ran out of Mocha testnet TIA and we are unable to post new blocks to Celestia due to a +[`Code: 19`](https://github.com/cosmos/cosmos-sdk/blob/main/types/errors/errors.go#L95) +error. This error is defined by Cosmos SDK as: + +```go +// ErrTxInMempoolCache defines an ABCI typed error where a tx already exists in the mempool. +ErrTxInMempoolCache = Register(RootCodespace, 19, "tx already in mempool") +``` + +In order to get around this error, and the same error on other Evolve chains, you will need to re-fund your Celestia account and increase the gas fee. This will override the transaction that is stuck in the mempool. + +If you top up the balance of your node and don't increase the gas fee, you will still encounter the `Code: 19` error because there is a transaction (posting block to DA) that is duplicate to one that already exists. In order to get around this, you'll need to increase the gas fee and restart the chain. + +### 🟠 Errors in this example {#errors} + +This is what the errors will look like if your DA node runs out of funding or you restart the chain without changing the gas fee: + +```bash +4:51PM INF submitting block to DA layer height=28126 module=BlockManager +4:51PM ERR DA layer submission failed error="Codespace: 'sdk', Code: 19, Message: " attempt=1 module=BlockManager +4:51PM ERR DA layer submission failed Error="Codespace: 'sdk', Code: 19, Message: " attempt=2 module=BlockManager +4:51PM ERR DA layer submission failed error="Codespace: 'sdk', Code: 19, Message: " attempt=3 module=BlockManager +``` + +### 💰 Re-fund your account {#refund-your-account} + +First, you'll need to send more tokens to the account running your Celestia node. If you didn't keep track of your key, you can run the following to get your address: + +```bash +cd $HOME && cd celestia-node +./cel-key list --keyring-backend test --node.type light --p2p.network +``` + +### 🛑 Stopping your chain {#stopping-your-chain} + +You can stop your chain by using `Control + C` in your terminal where the node is running. + +### ⛽ Increase the gas fee {#increase-gas-fee} + +To reiterate, before restarting the chain, you will need to increase the gas fee in order to avoid a `Code: 19` error. See the [How to configure gas price](/guides/config.md#da-gas-price) guide for more information. + +### 🔁 Restarting your chain {#restarting-your-chain} + +Follow the [restart chain](#restart-chain) section above. + +### 🛢️ Reduce gas fee & restart again {#reduce-gas-fee-restart-again} + +In order to save your TIA, we also recommend stopping the chain with `Control + C`, changing the gas fee back to the default (in our case, 8000 utia) and restarting the chain: + +🎊 Congrats! You've successfully restarted your Evolve chain after running out of TIA. diff --git a/docs/guides/use-tia-for-gas.md b/docs/guides/use-tia-for-gas.md new file mode 100644 index 0000000000..777381b0d6 --- /dev/null +++ b/docs/guides/use-tia-for-gas.md @@ -0,0 +1,260 @@ +# How to use IBC token (TIA) as gas token in your chain + +## 🌞 Introduction {#introduction} + +This tutorial will guide you through building a sovereign `gm-world` chain using Evolve, with TIA as the gas token. Unlike the [quick start guide](/guides/quick-start.md), which uses a native chain token for gas, this tutorial demonstrates how to integrate an IBC-enabled token, TIA, as the gas token within the chain, providing a deeper exploration of sovereign chain development. + +No prior understanding of the build process is required, just that it utilizes the [Cosmos SDK](https://github.com/cosmos/cosmos-sdk) for blockchain applications. + +## Requirements {#requirements} + +Before proceeding, ensure that you have completed the [build a chain](/guides/gm-world.md) tutorial, which covers setting-up, building and running your chain. + + + + +:::tip + +::: + + + +## Setup your local DA network {#setup-local-da} + +Your local DA network is already running if you followed the [quick start guide](/guides/quick-start.md) or the [build a chain](/guides/gm-world.md). If not, you can start it with the following command: + +```bash +curl -sSL https://ev.xyz/install-local-da.sh | bash -s {{constants.evolveLatestTag}} +``` + +## 🚀 Starting your chain {#start-your-chain} + +Start the chain, posting to the local DA network: + +```bash +gmd start --evolve.node.aggregator --evolve.da.address http://localhost:7980 --minimum-gas-prices="0.02ibc/C3E53D20BC7A4CC993B17C7971F8ECD06A433C10B6A96F4C4C3714F0624C56DA,0.025stake" +``` + +Note that we specified the gas token to be IBC TIA. We still haven't made an IBC connection to Celestia's Mocha testnet, however, if we assume our first channel will be an ICS-20 transfer channel to Celestia, we can already calculate the token denom using this formula: + +```js +"ibc/" + toHex(sha256(toUtf8("transfer/channel-0/utia"))).toUpperCase(); +``` + +Now you should see the logs of the running node: + +```bash +12:21PM INF starting node with ABCI CometBFT in-process module=server +12:21PM INF starting node with Evolve in-process module=server +12:21PM INF service start impl=multiAppConn module=proxy msg="Starting multiAppConn service" +12:21PM INF service start connection=query impl=localClient module=abci-client msg="Starting localClient service" +12:21PM INF service start connection=snapshot impl=localClient module=abci-client msg="Starting localClient service" +12:21PM INF service start connection=mempool impl=localClient module=abci-client msg="Starting localClient service" +12:21PM INF service start connection=consensus impl=localClient module=abci-client msg="Starting localClient service" +12:21PM INF service start impl=EventBus module=events msg="Starting EventBus service" +12:21PM INF service start impl=PubSub module=pubsub msg="Starting PubSub service" +12:21PM INF Using default mempool ttl MempoolTTL=25 module=BlockManager +12:21PM INF service start impl=IndexerService module=txindex msg="Starting IndexerService service" +12:21PM INF service start impl=RPC module=server msg="Starting RPC service" +12:21PM INF service start impl=Node module=server msg="Starting Node service" +12:21PM INF starting P2P client module=server +12:21PM INF serving HTTP listen address=127.0.0.1:26657 module=server +12:21PM INF listening on address=/ip4/127.0.0.1/tcp/26656/p2p/12D3KooWSicdPmMTLf9fJbSSHZc9UVP1CbNqKPpbYVbgxHvbhAUY module=p2p +12:21PM INF listening on address=/ip4/163.172.162.109/tcp/26656/p2p/12D3KooWSicdPmMTLf9fJbSSHZc9UVP1CbNqKPpbYVbgxHvbhAUY module=p2p +12:21PM INF no seed nodes - only listening for connections module=p2p +12:21PM INF working in aggregator mode block time=1000 module=server +12:21PM INF Creating and publishing block height=22 module=BlockManager +12:21PM INF starting gRPC server... address=127.0.0.1:9290 module=grpc-server +12:21PM INF finalized block block_app_hash=235D3710D61F347DBBBDD6FD63AA7687842D1EF9CB475C712856D7DA32F82F09 height=22 module=BlockManager num_txs_res=0 num_val_updates=0 +12:21PM INF executed block app_hash=235D3710D61F347DBBBDD6FD63AA7687842D1EF9CB475C712856D7DA32F82F09 height=22 module=BlockManager +12:21PM INF indexed block events height=22 module=txindex +... +``` + +## ✨ Connecting to Celestia Mocha testnet using IBC {#ibc-to-celestia} + +Next, we will establish an IBC connection with the Celestia Mocha testnet to enable TIA transfers for gas usage on our chain. + +Install the IBC relayer: + +```bash +git clone --depth 1 --branch v2.5.2 https://github.com/cosmos/relayer.git /tmp/relayer +cd /tmp/relayer +make install +``` + +Configure the relayer: + +```bash +rly config init + +mkdir -p "$HOME/.relayer/keys/{gm,mocha-4}" + +echo "global: + api-listen-addr: :5183 + timeout: 10s + memo: '' + light-cache-size: 20 + log-level: info + ics20-memo-limit: 0 + max-receiver-size: 150 +chains: + gm_chain: + type: cosmos + value: + key-directory: '$HOME/.relayer/keys/gm' + key: a + chain-id: gm + rpc-addr: http://localhost:26657 + account-prefix: gm + keyring-backend: test + gas-adjustment: 1.5 + gas-prices: 0.025stake + min-gas-amount: 0 + max-gas-amount: 0 + debug: false + timeout: 20s + block-timeout: '' + output-format: json + sign-mode: direct + extra-codecs: [] + coin-type: 118 + signing-algorithm: '' + broadcast-mode: batch + min-loop-duration: 0s + extension-options: [] + feegrants: null + mocha: + type: cosmos + value: + key-directory: '$HOME/.relayer/keys/mocha-4' + key: a + chain-id: mocha-4 + rpc-addr: https://celestia-testnet-rpc.publicnode.com:443 + account-prefix: celestia + keyring-backend: test + gas-adjustment: 1.5 + gas-prices: 0.15utia + min-gas-amount: 0 + max-gas-amount: 0 + debug: false + timeout: 20s + block-timeout: '' + output-format: json + sign-mode: direct + extra-codecs: [] + coin-type: 118 + signing-algorithm: '' + broadcast-mode: batch + min-loop-duration: 0s + extension-options: [] + feegrants: null +paths: + gm_mocha-4: + src: + chain-id: gm + dst: + chain-id: mocha-4 + src-channel-filter: + rule: '' + channel-list: [] +" > "$HOME/.relayer/config/config.yaml" + +rly keys restore gm_chain a "regret resist either bid upon yellow leaf early symbol win market vital" +rly keys restore mocha a "regret resist either bid upon yellow leaf early symbol win market vital" +``` + +Get the relayer accounts: + +```bash +rly address gm_chain a # => gm1jqevcsld0dqpjp3csfg7alkv3lehvn8uswknrc +rly address mocha a # => celestia1jqevcsld0dqpjp3csfg7alkv3lehvn8u04ymsu +``` + +Note: These accounts should always be the same because of the hardcoded mnemonics that we've loaded in the `rly keys restore` step. + +Fund the relayer on our chain: + +```bash +gmd tx bank send gm-key-2 gm1jqevcsld0dqpjp3csfg7alkv3lehvn8uswknrc 10000000stake --keyring-backend test --chain-id gm --fees 5000stake -y +``` + +Fund the relayer on the Celestia Mocha testnet: + +[Mocha Testnet Faucet Instructions](https://docs.celestia.org/how-to-guides/mocha-testnet#mocha-testnet-faucet). + +Verify the relayer is funded: + +```bash +rly q balance mocha a # => address {celestia1jqevcsld0dqpjp3csfg7alkv3lehvn8u04ymsu} balance {10000000utia} +rly q balance gm_chain a # => address {gm1jqevcsld0dqpjp3csfg7alkv3lehvn8uswknrc} balance {10000000stake} +``` + +Create IBC clients: + +```bash +rly tx client gm_chain mocha gm_mocha-4 --override +rly tx client mocha gm_chain gm_mocha-4 --override +``` + +Create IBC connection: + +```bash +rly tx connection gm_mocha-4 +``` + +Create IBC channel: + +```bash +rly tx channel gm_mocha-4 --src-port transfer --dst-port transfer --version ics20-1 +``` + +Start the relayer: + +```bash +rly start gm_mocha-4 +``` + +Transfer TIA from Mocha to our chain: + +```bash +ACCOUNT_ON_CHAIN="$(evolve keys show -a --keyring-backend test gm-key-2)" +CHANNEL_ID_ON_MOCHA="$(rly q channels mocha gm_chain | jq -r .channel_id | tail -1)" + +rly tx transfer mocha gm_chain 1000000utia "$ACCOUNT_ON_CHAIN" "$CHANNEL_ID_ON_MOCHA" --path gm_mocha-4 +``` + +Verify the account on our chain is funded with IBC TIA: + +```bash +gmd query bank balances "$(evolve keys show -a --keyring-backend test gm-key-2)" +# => +# balances: +# - amount: "1000000" +# denom: ibc/C3E53D20BC7A4CC993B17C7971F8ECD06A433C10B6A96F4C4C3714F0624C56DA +# - amount: "9999999999999999989995000" +# denom: stake +# pagination: +# total: "2" +``` + +## 💸 Transactions {#transactions} + +Finally, send a transaction on our chain using IBC TIA as the gas token: + +```bash +ACCOUNT_ON_CHAIN="$(evolve keys show -a --keyring-backend test gm-key-2)" + +# Send the transaction +TX_HASH=$(evolve tx bank send "$ACCOUNT_ON_CHAIN" "$ACCOUNT_ON_CHAIN" 1stake --keyring-backend test --chain-id gm --gas-prices 0.02ibc/C3E53D20BC7A4CC993B17C7971F8ECD06A433C10B6A96F4C4C3714F0624C56DA -y --output json | jq -r .txhash) + +# Verify success +gmd q tx "$TX_HASH" --output json | jq .code # => 0 +``` + +## 🎉 Next steps + +Congratulations! You've built a local chain that posts to a local DA network and uses TIA as the gas token! diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000000..f80a9d5216 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,36 @@ +--- +# https://vitepress.dev/reference/default-theme-home-page +layout: home +titleTemplate: ':title' + +hero: + image: + src: /img/logo.png + alt: Evolve Logo + text: "Own It. Shape It. Launch It" + tagline: | + Modular. Production-ready. + Yours. + Built on Celestia, Evolve enables developers a direct path to shipping custom networks. + actions: + - theme: brand + text: Quick start + link: /guides/quick-start + - theme: alt + text: Introduction + link: /learn/about + +features: + - title: Full Control Over Execution + details: Design your network exactly how you want it. Choose your VM, customize your execution environment, and maintain complete control without middlemen or revenue share. + link: /learn/about#why-evolve + icon: 🚀 + - title: Speed to Traction + details: Get to market fast with infrastructure that adapts to your app—not the other way around. Skip the complexity and start building what matters; your product. + link: /learn/execution + icon: ⚡ + - title: No Validator Overhead + details: Skip the complexity of running validators. Focus on building your application while Celestia handles consensus and data availability. + link: /learn/about + icon: 🛡️ +--- diff --git a/docs/learn/about.md b/docs/learn/about.md new file mode 100644 index 0000000000..e4df8c75eb --- /dev/null +++ b/docs/learn/about.md @@ -0,0 +1,95 @@ +# Introduction + +Evolve is the fastest way to launch your own modular network — without validator overhead or token lock-in. + +Built on Celestia, Evolve offers L1-level control with L2-level performance. + +This isn't a toolkit. It's a launch stack. + +No fees. No middlemen. No revenue share. + +## What is Evolve? + +Evolve is a launch stack for L1s. It gives you full control over execution — without CometBFT, validator ops, or lock-in. + +It's [open-source](https://github.com/evstack/ev-node), production-ready, and fully composable. + +At its core is \`ev-node\`, a modular node that exposes an [Execution interface](https://github.com/evstack/ev-node/blob/main/core/execution/execution.go), — letting you bring any VM or execution logic, including Cosmos SDK or custom-built runtimes. + +Evolving from Cosmos SDK? + +Migrate without rewriting your stack. Bring your logic and state to Evolve and shed validator overhead — all while gaining performance and execution freedom. + +Evolve is how you launch your network. Modular. Production-ready. Yours. + +With Evolve, you get: + +- Full control over execution \- use any VM +- Low-cost launch — no emissions, no validator inflation +- Speed to traction — from local devnet to testnet in minutes +- Keep sequencer revenue — monetize directly +- Optional L1 validator network for fast finality and staking + +Powered by Celestia — toward 1GB blocks, multi-VM freedom, and execution without compromising flexibility or cost. + +## What problems is Evolve solving? + +### 1\. Scalability and customizability + +Deploying your decentralized application as a smart contract on a shared blockchain has many limitations. Your smart contract has to share computational resources with every other application, so scalability is limited. + +Plus, you're restricted to the execution environment that the shared blockchain uses, so developer flexibility is limited as well. + +### 2\. Security and time to market + +Deploying a new chain might sound like the perfect solution for the problems listed above. While it's somewhat true, deploying a new layer 1 chain presents a complex set of challenges and trade-offs for developers looking to build blockchain products. + +Deploying a legacy layer 1 has huge barriers to entry: time, capital, token emissions and expertise. + +In order to secure the network, developers must bootstrap a sufficiently secure set of validators, incurring the overhead of managing a full consensus network. This requires paying validators with inflationary tokens, putting the network's business sustainability at risk. Network effects are also critical for success, but can be challenging to achieve as the network must gain widespread adoption to be secure and valuable. + +In a potential future with millions of chains, it's unlikely all of those chains will be able to sustainably attract a sufficiently secure and decentralized validator set. + +## Why Evolve? + +Evolve solves the challenges encountered during the deployment of a smart contract or a new layer 1, by minimizing these tradeoffs through the implementation of evolve chains. + +With Evolve, developers can benefit from: + +- **Shared security**: Chains inherit security from a data availability layer, by posting blocks to it. Chains reduce the trust assumptions placed on chain sequencers by allowing full nodes to download and verify the transactions in the blocks posted by the sequencer. For optimistic or zk-chains, in case of fraudulent blocks, full nodes can generate fraud or zk-proofs, which they can share with the rest of the network, including light nodes. Our roadmap includes the ability for light clients to receive and verify proofs, so that everyday users can enjoy high security guarantees. + +- **Scalability:** Evolve chains are deployed on specialized data availability layers like Celestia, which directly leverages the scalability of the DA layer. Additionally, chain transactions are executed off-chain rather than on the data availability layer. This means chains have their own dedicated computational resources, rather than sharing computational resources with other applications. + +- **Customizability:** Evolve is built as an open source modular framework, to make it easier for developers to reuse the four main components and customize their chains. These components are data availability layers, execution environments, proof systems, and sequencer schemes. + +- **Faster time-to-market:** Evolve eliminates the need to bootstrap a validator set, manage a consensus network, incur high economic costs, and face other trade-offs that come with deploying a legacy layer 1\. Evolve's goal is to make deploying a chain as easy as it is to deploy a smart contract, cutting the time it takes to bring blockchain products to market from months (or even years) to just minutes. + +- **Sovereignty**: Evolve also enables developers to deploy chains for cases where communities require sovereignty. + +## How can you use Evolve? + +As briefly mentioned above, Evolve could be used in many different ways. From chains, to settlement layers, and in the future even to L3s. + +### Chain with any VM + +Evolve gives developers the flexibility to use pre-existing ABCI-compatible state machines or create a custom state machine tailored to their chain needs. Evolve does not restrict the use of any specific virtual machine, allowing developers to experiment and bring innovative applications to life. + +### Cosmos SDK + +Similarly to how developers utilize the Cosmos SDK to build a layer 1 chain, the Cosmos SDK could be utilized to create a Evolve-compatible chain. Cosmos-SDK has great [documentation](https://docs.cosmos.network/main) and tooling that developers can leverage to learn. + +Another possibility is taking an existing layer 1 built with the Cosmos SDK and deploying it as a Evolve chain. Evolve gives your network a forward path. Migrate seamlessly, keep your logic, and evolve into a modular, high-performance system without CometBFT bottlenecks and zero validator overhead. + +### Build a settlement layer + +[Settlement layers](https://celestia.org/learn/modular-settlement-layers/settlement-in-the-modular-stack/) are ideal for developers who want to avoid deploying chains. They provide a platform for chains to verify proofs and resolve disputes. Additionally, they act as a hub for chains to facilitate trust-minimized token transfers and liquidity sharing between chains that share the same settlement layer. Think of settlement layers as a special type of execution layer. + +## When can you use Evolve? + +As of today, Evolve provides a single sequencer, an execution interface (Engine API or ABCI), and a connection to Celestia. + +We're currently working on implementing many new and exciting features such as light nodes and state fraud proofs. + +Head down to the next section to learn more about what's coming for Evolve. If you're ready to start building, you can skip to the [Guides](/guides/quick-start.md) section. + +Spoiler alert, whichever you choose, it's going to be a great rabbit hole\! diff --git a/docs/learn/config.md b/docs/learn/config.md new file mode 100644 index 0000000000..133dbea974 --- /dev/null +++ b/docs/learn/config.md @@ -0,0 +1,775 @@ +# Config + +This document provides a comprehensive reference for all configuration options available in Evolve. Understanding these configurations will help you tailor Evolve's behavior to your specific needs, whether you're running an aggregator, a full node, or a light client. + +## Table of Contents + +- [Introduction to Configurations](#introduction-to-configurations) +- [Base Configuration](#base-configuration) + - [Root Directory](#root-directory) + - [Database Path](#database-path) + - [Chain ID](#chain-id) +- [Node Configuration (`node`)](#node-configuration-node) + - [Aggregator Mode](#aggregator-mode) + - [Light Client Mode](#light-client-mode) + - [Block Time](#block-time) + - [Maximum Pending Blocks](#maximum-pending-blocks) + - [Lazy Mode (Lazy Aggregator)](#lazy-mode-lazy-aggregator) + - [Lazy Block Interval](#lazy-block-interval) + - [Trusted Hash](#trusted-hash) +- [Data Availability Configuration (`da`)](#data-availability-configuration-da) + - [DA Service Address](#da-service-address) + - [DA Authentication Token](#da-authentication-token) + - [DA Gas Price](#da-gas-price) + - [DA Gas Multiplier](#da-gas-multiplier) + - [DA Submit Options](#da-submit-options) + - [DA Namespace](#da-namespace) + - [DA Block Time](#da-block-time) + - [DA Start Height](#da-start-height) + - [DA Mempool TTL](#da-mempool-ttl) +- [P2P Configuration (`p2p`)](#p2p-configuration-p2p) + - [P2P Listen Address](#p2p-listen-address) + - [P2P Peers](#p2p-peers) + - [P2P Blocked Peers](#p2p-blocked-peers) + - [P2P Allowed Peers](#p2p-allowed-peers) +- [RPC Configuration (`rpc`)](#rpc-configuration-rpc) + - [RPC Server Address](#rpc-server-address) +- [Instrumentation Configuration (`instrumentation`)](#instrumentation-configuration-instrumentation) + - [Enable Prometheus Metrics](#enable-prometheus-metrics) + - [Prometheus Listen Address](#prometheus-listen-address) + - [Maximum Open Connections](#maximum-open-connections) + - [Enable Pprof Profiling](#enable-pprof-profiling) + - [Pprof Listen Address](#pprof-listen-address) +- [Logging Configuration (`log`)](#logging-configuration-log) + - [Log Level](#log-level) + - [Log Format](#log-format) + - [Log Trace (Stack Traces)](#log-trace-stack-traces) +- [Signer Configuration (`signer`)](#signer-configuration-signer) + - [Signer Type](#signer-type) + - [Signer Path](#signer-path) + - [Signer Passphrase](#signer-passphrase) + +## Configs + +Evolve configurations can be managed through a YAML file (typically `evolve.yaml` located in `~/.evolve/config/` or `/config/`) and command-line flags. The system prioritizes configurations in the following order (highest priority first): + +1. **Command-line flags:** Override all other settings. +2. **YAML configuration file:** Values specified in the `config.yaml` file. +3. **Default values:** Predefined defaults within Evolve. + +Environment variables can also be used, typically prefixed with your executable's name (e.g., `YOURAPP_CHAIN_ID="my-chain"`). + +## Base Configuration + +These are fundamental settings for your Evolve node. + +### Root Directory + +**Description:** +The root directory where Evolve stores its data, including the database and configuration files. This is a foundational setting that dictates where all other file paths are resolved from. + +**YAML:** +This option is not set within the YAML configuration file itself, as it specifies the location *of* the configuration file and other application data. + +**Command-line Flag:** +`--home ` +*Example:* `--home /mnt/data/evolve_node` +*Default:* `~/.evolve` (or a directory derived from the application name if `defaultHome` is customized). +*Constant:* `FlagRootDir` + +### Database Path + +**Description:** +The path, relative to the Root Directory, where the Evolve database will be stored. This database contains blockchain state, blocks, and other critical node data. + +**YAML:** +Set this in your configuration file at the top level: + +```yaml +db_path: "data" +``` + +**Command-line Flag:** +`--rollkit.db_path ` +*Example:* `--rollkit.db_path "node_db"` +*Default:* `"data"` +*Constant:* `FlagDBPath` + +### Chain ID + +**Description:** +The unique identifier for your chain. This ID is used to differentiate your network from others and is crucial for network communication and transaction validation. + +**YAML:** +Set this in your configuration file at the top level: + +```yaml +chain_id: "my-evolve-chain" +``` + +**Command-line Flag:** +`--chain_id ` +*Example:* `--chain_id "super_rollup_testnet_v1"` +*Default:* `"evolve"` +*Constant:* `FlagChainID` + +## Node Configuration (`node`) + +Settings related to the core behavior of the Evolve node, including its mode of operation and block production parameters. + +**YAML Section:** + +```yaml +node: + # ... node configurations ... +``` + +### Aggregator Mode + +**Description:** +If true, the node runs in aggregator mode. Aggregators are responsible for producing blocks by collecting transactions, ordering them, and proposing them to the network. + +**YAML:** + +```yaml +node: + aggregator: true +``` + +**Command-line Flag:** +`--rollkit.node.aggregator` (boolean, presence enables it) +*Example:* `--rollkit.node.aggregator` +*Default:* `false` +*Constant:* `FlagAggregator` + +### Light Client Mode + +**Description:** +If true, the node runs in light client mode. Light clients rely on full nodes for block headers and state information, offering a lightweight way to interact with the chain without storing all data. + +**YAML:** + +```yaml +node: + light: true +``` + +**Command-line Flag:** +`--rollkit.node.light` (boolean, presence enables it) +*Example:* `--rollkit.node.light` +*Default:* `false` +*Constant:* `FlagLight` + +### Block Time + +**Description:** +The target time interval between consecutive blocks produced by an aggregator. This duration (e.g., "500ms", "1s", "5s") dictates the pace of block production. + +**YAML:** + +```yaml +node: + block_time: "1s" +``` + +**Command-line Flag:** +`--rollkit.node.block_time ` +*Example:* `--rollkit.node.block_time 2s` +*Default:* `"1s"` +*Constant:* `FlagBlockTime` + +### Maximum Pending Blocks + +**Description:** +The maximum number of blocks that can be pending Data Availability (DA) submission. When this limit is reached, the aggregator pauses block production until some blocks are confirmed on the DA layer. Use 0 for no limit. This helps manage resource usage and DA layer capacity. + +**YAML:** + +```yaml +node: + max_pending_blocks: 100 +``` + +**Command-line Flag:** +`--rollkit.node.max_pending_blocks ` +*Example:* `--rollkit.node.max_pending_blocks 50` +*Default:* `0` (no limit) +*Constant:* `FlagMaxPendingBlocks` + +### Lazy Mode (Lazy Aggregator) + +**Description:** +Enables lazy aggregation mode. In this mode, blocks are produced only when new transactions are available in the mempool or after the `lazy_block_interval` has passed. This optimizes resource usage by avoiding the creation of empty blocks during periods of inactivity. + +**YAML:** + +```yaml +node: + lazy_mode: true +``` + +**Command-line Flag:** +`--rollkit.node.lazy_mode` (boolean, presence enables it) +*Example:* `--rollkit.node.lazy_mode` +*Default:* `false` +*Constant:* `FlagLazyAggregator` + +### Lazy Block Interval + +**Description:** +The maximum time interval between blocks when running in lazy aggregation mode (`lazy_mode`). This ensures that blocks are produced periodically even if there are no new transactions, keeping the chain active. This value is generally larger than `block_time`. + +**YAML:** + +```yaml +node: + lazy_block_interval: "30s" +``` + +**Command-line Flag:** +`--rollkit.node.lazy_block_interval ` +*Example:* `--rollkit.node.lazy_block_interval 1m` +*Default:* `"30s"` +*Constant:* `FlagLazyBlockTime` + +### Trusted Hash + +**Description:** +The initial trusted hash used to bootstrap the header exchange service. This allows nodes to start synchronizing from a specific, trusted point in the chain history instead of from the genesis block. When provided, the node will fetch the corresponding header/block from peers using this hash. If not provided, the node attempts to sync from genesis. + +**YAML:** + +```yaml +node: + trusted_hash: "YOUR_TRUSTED_HASH_HEX_STRING" +``` + +**Command-line Flag:** +`--rollkit.node.trusted_hash ` +*Example:* `--rollkit.node.trusted_hash ABCDEF012345...` +*Default:* `""` (empty, sync from genesis) +*Constant:* `FlagTrustedHash` + +## Data Availability Configuration (`da`) + +Parameters for connecting and interacting with the Data Availability (DA) layer, which Evolve uses to publish block data. + +**YAML Section:** + +```yaml +da: + # ... DA configurations ... +``` + +### DA Service Address + +**Description:** +The network address (host:port) of the Data Availability layer service. Evolve connects to this endpoint to submit and retrieve block data. + +**YAML:** + +```yaml +da: + address: "localhost:26659" +``` + +**Command-line Flag:** +`--rollkit.da.address ` +*Example:* `--rollkit.da.address 192.168.1.100:26659` +*Default:* `""` (empty, must be configured if DA is used) +*Constant:* `FlagDAAddress` + +### DA Authentication Token + +**Description:** +The authentication token required to interact with the DA layer service, if the service mandates authentication. + +**YAML:** + +```yaml +da: + auth_token: "YOUR_DA_AUTH_TOKEN" +``` + +**Command-line Flag:** +`--rollkit.da.auth_token ` +*Example:* `--rollkit.da.auth_token mysecrettoken` +*Default:* `""` (empty) +*Constant:* `FlagDAAuthToken` + +### DA Gas Price + +**Description:** +The gas price to use for transactions submitted to the DA layer. A value of -1 indicates automatic gas price determination (if supported by the DA layer). Higher values may lead to faster inclusion of data. + +**YAML:** + +```yaml +da: + gas_price: 0.025 +``` + +**Command-line Flag:** +`--rollkit.da.gas_price ` +*Example:* `--rollkit.da.gas_price 0.05` +*Default:* `-1` (automatic) +*Constant:* `FlagDAGasPrice` + +### DA Gas Multiplier + +**Description:** +A multiplier applied to the gas price when retrying failed DA submissions. Values greater than 1 increase the gas price on retries, potentially improving the chances of successful inclusion. + +**YAML:** + +```yaml +da: + gas_multiplier: 1.1 +``` + +**Command-line Flag:** +`--rollkit.da.gas_multiplier ` +*Example:* `--rollkit.da.gas_multiplier 1.5` +*Default:* `1.0` (no multiplication) +*Constant:* `FlagDAGasMultiplier` + +### DA Submit Options + +**Description:** +Additional options passed to the DA layer when submitting data. The format and meaning of these options depend on the specific DA implementation being used. + +**YAML:** + +```yaml +da: + submit_options: "{"key":"value"}" # Example, format depends on DA layer +``` + +**Command-line Flag:** +`--rollkit.da.submit_options ` +*Example:* `--rollkit.da.submit_options '{"custom_param":true}'` +*Default:* `""` (empty) +*Constant:* `FlagDASubmitOptions` + +### DA Namespace + +**Description:** +The namespace ID used when submitting blobs (block data) to the DA layer. This helps segregate data from different chains or applications on a shared DA layer. + +**YAML:** + +```yaml +da: + namespace: "MY_UNIQUE_NAMESPACE_ID" +``` + +**Command-line Flag:** +`--rollkit.da.namespace ` +*Example:* `--rollkit.da.namespace 0x1234567890abcdef` +*Default:* `""` (empty, must be configured) +*Constant:* `FlagDANamespace` + +### DA Block Time + +**Description:** +The average block time of the Data Availability chain (specified as a duration string, e.g., "15s", "1m"). This value influences: + +- The frequency of DA layer syncing. +- The maximum backoff time for retrying DA submissions. +- Calculation of transaction expiration when multiplied by `mempool_ttl`. + +**YAML:** + +```yaml +da: + block_time: "6s" +``` + +**Command-line Flag:** +`--rollkit.da.block_time ` +*Example:* `--rollkit.da.block_time 12s` +*Default:* `"6s"` +*Constant:* `FlagDABlockTime` + +### DA Start Height + +**Description:** +The block height on the DA layer from which Evolve should begin syncing. This is useful when deploying a new chain on an existing DA chain, allowing it to ignore historical data before its inception. + +**YAML:** + +```yaml +da: + start_height: 100000 +``` + +**Command-line Flag:** +`--rollkit.da.start_height ` +*Example:* `--rollkit.da.start_height 500000` +*Default:* `0` (sync from the beginning) +*Constant:* `FlagDAStartHeight` + +### DA Mempool TTL + +**Description:** +The number of DA blocks after which a transaction submitted to the DA layer is considered expired and potentially dropped from the DA layer's mempool. This also controls the retry backoff timing for DA submissions. + +**YAML:** + +```yaml +da: + mempool_ttl: 20 +``` + +**Command-line Flag:** +`--rollkit.da.mempool_ttl ` +*Example:* `--rollkit.da.mempool_ttl 30` +*Default:* `20` +*Constant:* `FlagDAMempoolTTL` + +## P2P Configuration (`p2p`) + +Settings for peer-to-peer networking, enabling nodes to discover each other, exchange blocks, and share transactions. + +**YAML Section:** + +```yaml +p2p: + # ... P2P configurations ... +``` + +### P2P Listen Address + +**Description:** +The network address (host:port) on which the Evolve node will listen for incoming P2P connections from other nodes. + +**YAML:** + +```yaml +p2p: + listen_address: "0.0.0.0:7676" +``` + +**Command-line Flag:** +`--rollkit.p2p.listen_address ` +*Example:* `--rollkit.p2p.listen_address /ip4/127.0.0.1/tcp/26656` +*Default:* `"/ip4/0.0.0.0/tcp/7676"` +*Constant:* `FlagP2PListenAddress` + +### P2P Peers + +**Description:** +A comma-separated list of peer addresses (e.g., multiaddresses) that the node will attempt to connect to for bootstrapping its P2P connections. These are often referred to as seed nodes. + +**YAML:** + +```yaml +p2p: + peers: "/ip4/some_peer_ip/tcp/7676/p2p/PEER_ID1,/ip4/another_peer_ip/tcp/7676/p2p/PEER_ID2" +``` + +**Command-line Flag:** +`--rollkit.p2p.peers ` +*Example:* `--rollkit.p2p.peers /dns4/seed.example.com/tcp/26656/p2p/12D3KooW...` +*Default:* `""` (empty) +*Constant:* `FlagP2PPeers` + +### P2P Blocked Peers + +**Description:** +A comma-separated list of peer IDs that the node should block from connecting. This can be used to prevent connections from known malicious or problematic peers. + +**YAML:** + +```yaml +p2p: + blocked_peers: "PEER_ID_TO_BLOCK1,PEER_ID_TO_BLOCK2" +``` + +**Command-line Flag:** +`--rollkit.p2p.blocked_peers ` +*Example:* `--rollkit.p2p.blocked_peers 12D3KooW...,12D3KooX...` +*Default:* `""` (empty) +*Constant:* `FlagP2PBlockedPeers` + +### P2P Allowed Peers + +**Description:** +A comma-separated list of peer IDs that the node should exclusively allow connections from. If this list is non-empty, only peers in this list will be able to connect. + +**YAML:** + +```yaml +p2p: + allowed_peers: "PEER_ID_TO_ALLOW1,PEER_ID_TO_ALLOW2" +``` + +**Command-line Flag:** +`--rollkit.p2p.allowed_peers ` +*Example:* `--rollkit.p2p.allowed_peers 12D3KooY...,12D3KooZ...` +*Default:* `""` (empty, allow all unless blocked) +*Constant:* `FlagP2PAllowedPeers` + +## RPC Configuration (`rpc`) + +Settings for the Remote Procedure Call (RPC) server, which allows clients and applications to interact with the Evolve node. + +**YAML Section:** + +```yaml +rpc: + # ... RPC configurations ... +``` + +### RPC Server Address + +**Description:** +The network address (host:port) to which the RPC server will bind and listen for incoming requests. + +**YAML:** + +```yaml +rpc: + address: "127.0.0.1:7331" +``` + +**Command-line Flag:** +`--rollkit.rpc.address ` +*Example:* `--rollkit.rpc.address 0.0.0.0:26657` +*Default:* `"127.0.0.1:7331"` +*Constant:* `FlagRPCAddress` + +## Instrumentation Configuration (`instrumentation`) + +Settings for enabling and configuring metrics and profiling endpoints, useful for monitoring node performance and debugging. + +**YAML Section:** + +```yaml +instrumentation: + # ... instrumentation configurations ... +``` + +### Enable Prometheus Metrics + +**Description:** +If true, enables the Prometheus metrics endpoint, allowing Prometheus to scrape operational data from the Evolve node. + +**YAML:** + +```yaml +instrumentation: + prometheus: true +``` + +**Command-line Flag:** +`--rollkit.instrumentation.prometheus` (boolean, presence enables it) +*Example:* `--rollkit.instrumentation.prometheus` +*Default:* `false` +*Constant:* `FlagPrometheus` + +### Prometheus Listen Address + +**Description:** +The network address (host:port) where the Prometheus metrics server will listen for scraping requests. + +See [Metrics](/guides/metrics.md) for more details on what metrics are exposed. + +**YAML:** + +```yaml +instrumentation: + prometheus_listen_addr: ":2112" +``` + +**Command-line Flag:** +`--rollkit.instrumentation.prometheus_listen_addr ` +*Example:* `--rollkit.instrumentation.prometheus_listen_addr 0.0.0.0:9090` +*Default:* `":2112"` +*Constant:* `FlagPrometheusListenAddr` + +### Maximum Open Connections + +**Description:** +The maximum number of simultaneous connections allowed for the metrics server (e.g., Prometheus endpoint). + +**YAML:** + +```yaml +instrumentation: + max_open_connections: 100 +``` + +**Command-line Flag:** +`--rollkit.instrumentation.max_open_connections ` +*Example:* `--rollkit.instrumentation.max_open_connections 50` +*Default:* (Refer to `DefaultInstrumentationConfig()` in code, typically a reasonable number like 100) +*Constant:* `FlagMaxOpenConnections` + +### Enable Pprof Profiling + +**Description:** +If true, enables the pprof HTTP endpoint, which provides runtime profiling data for debugging performance issues. Accessing these endpoints can help diagnose CPU and memory usage. + +**YAML:** + +```yaml +instrumentation: + pprof: true +``` + +**Command-line Flag:** +`--rollkit.instrumentation.pprof` (boolean, presence enables it) +*Example:* `--rollkit.instrumentation.pprof` +*Default:* `false` +*Constant:* `FlagPprof` + +### Pprof Listen Address + +**Description:** +The network address (host:port) where the pprof HTTP server will listen for profiling requests. + +**YAML:** + +```yaml +instrumentation: + pprof_listen_addr: "localhost:6060" +``` + +**Command-line Flag:** +`--rollkit.instrumentation.pprof_listen_addr ` +*Example:* `--rollkit.instrumentation.pprof_listen_addr 0.0.0.0:6061` +*Default:* `"localhost:6060"` +*Constant:* `FlagPprofListenAddr` + +## Logging Configuration (`log`) + +Settings that control the verbosity and format of log output from the Evolve node. These are typically set via global flags. + +**YAML Section:** + +```yaml +log: + # ... logging configurations ... +``` + +### Log Level + +**Description:** +Sets the minimum severity level for log messages to be displayed. Common levels include `debug`, `info`, `warn`, `error`. + +**YAML:** + +```yaml +log: + level: "info" +``` + +**Command-line Flag:** +`--log.level ` (Note: some applications might use a different flag name like `--log_level`) +*Example:* `--log.level debug` +*Default:* `"info"` +*Constant:* `FlagLogLevel` (value: "evolve.log.level", but often overridden by global app flags) + +### Log Format + +**Description:** +Sets the format for log output. Common formats include `text` (human-readable) and `json` (structured, machine-readable). + +**YAML:** + +```yaml +log: + format: "text" +``` + +**Command-line Flag:** +`--log.format ` (Note: some applications might use a different flag name like `--log_format`) +*Example:* `--log.format json` +*Default:* `"text"` +*Constant:* `FlagLogFormat` (value: "evolve.log.format", but often overridden by global app flags) + +### Log Trace (Stack Traces) + +**Description:** +If true, enables the inclusion of stack traces in error logs. This can be very helpful for debugging issues by showing the call stack at the point of an error. + +**YAML:** + +```yaml +log: + trace: false +``` + +**Command-line Flag:** +`--log.trace` (boolean, presence enables it; Note: some applications might use a different flag name like `--log_trace`) +*Example:* `--log.trace` +*Default:* `false` +*Constant:* `FlagLogTrace` (value: "evolve.log.trace", but often overridden by global app flags) + +## Signer Configuration (`signer`) + +Settings related to the signing mechanism used by the node, particularly for aggregators that need to sign blocks. + +**YAML Section:** + +```yaml +signer: + # ... signer configurations ... +``` + +### Signer Type + +**Description:** +Specifies the type of remote signer to use. Common options might include `file` (for key files) or `grpc` (for connecting to a remote signing service). + +**YAML:** + +```yaml +signer: + signer_type: "file" +``` + +**Command-line Flag:** +`--rollkit.signer.type ` +*Example:* `--rollkit.signer.type grpc` +*Default:* (Depends on application, often "file" or none if not an aggregator) +*Constant:* `FlagSignerType` + +### Signer Path + +**Description:** +The path to the signer file (if `signer_type` is `file`) or the address of the remote signer service (if `signer_type` is `grpc` or similar). + +**YAML:** + +```yaml +signer: + signer_path: "/path/to/priv_validator_key.json" # For file signer + # signer_path: "localhost:9000" # For gRPC signer +``` + +**Command-line Flag:** +`--rollkit.signer.path ` +*Example:* `--rollkit.signer.path ./keys/mykey.pem` +*Default:* (Depends on application) +*Constant:* `FlagSignerPath` + +### Signer Passphrase + +**Description:** +The passphrase required to decrypt or access the signer key, particularly if using a `file` signer and the key is encrypted, or if the aggregator mode is enabled and requires it. This flag is not directly a field in the `SignerConfig` struct but is used in conjunction with it. + +**YAML:** +This is typically not stored in the YAML file for security reasons but provided via flag or environment variable. + +**Command-line Flag:** +`--rollkit.signer.passphrase ` +*Example:* `--rollkit.signer.passphrase "mysecretpassphrase"` +*Default:* `""` (empty) +*Constant:* `FlagSignerPassphrase` +*Note:* Be cautious with providing passphrases directly on the command line in shared environments due to history logging. Environment variables or secure input methods are often preferred. + +--- + +This reference should help you configure your Evolve node effectively. Always refer to the specific version of Evolve you are using, as options and defaults may change over time. diff --git a/docs/learn/data-availability.md b/docs/learn/data-availability.md new file mode 100644 index 0000000000..7c7b52e60f --- /dev/null +++ b/docs/learn/data-availability.md @@ -0,0 +1,33 @@ +# Data Availability in Evolve + +Data availability (DA) is a core of Evolve's. Evolve utilize's data availability ensures that all transaction data and block information required to verify the chain's state is accessible to anyone running a node or light client. + +Learn more about data availability: + +- [What is DA](https://celestia.org/what-is-da/) +- [The importance of DA for Rollups](https://medium.com/zeeve/exploring-data-availability-layer-and-its-importance-in-rollups-0a4fbf2e0ffc) + +## How Evolve Handles Data Availability + +Evolve is designed to be DA-agnostic, meaning it can integrate with different data availability layers depending on your needs. The main options are: + +- **Local Data Availability (Local DA):** + - Used for development, testing, and local deployments. + - Not secure for production, as data can be withheld by the node operator. + +- **External Data Availability Layer (DA Interface):** + - Used for production and secure deployments. + - Evolve can post block data to any external DA layer that implements the Evolve [DA interface](https://github.com/evstack/ev-node/blob/main/core/da/da.go#L11) (e.g., Celestia). + - Anyone can verify that the data is available and reconstruct the chain state, depending on the guarantees of the chosen DA layer. + +## Best Practices + +- **Use Local DA only for development and testing locally.** +- **Alternatively, you can use [Celestia testnets](https://docs.celestia.org/how-to-guides/participate).** +- **For production, always use a decentralized DA layer that implements the Evolve DA interface.** + +## Learn More + +- [Set up a local DA](/guides/da/local-da.md) +- [Set up Celestia DA](/guides/da/celestia-da.md) +- [Celestia Docs](https://docs.celestia.org/) diff --git a/docs/learn/execution.md b/docs/learn/execution.md new file mode 100644 index 0000000000..c2c76503e8 --- /dev/null +++ b/docs/learn/execution.md @@ -0,0 +1,31 @@ +# Execution Layers in Evolve + +Evolve is designed to be modular and flexible, allowing different execution layers to be plugged in. Evolve defines a general-purpose execution interface ([see execution.go](https://github.com/evstack/ev-node/blob/main/core/execution/execution.go)) that enables developers to integrate any compatible application as the chain's execution layer. + +This means you can use a variety of Cosmos SDK or Reth compatible applications as the execution environment for your chain: choose the execution environment that best fits your use case. + +## Supported Execution Layers + +### Cosmos SDK Execution Layer + +Evolve natively supports Cosmos SDK-based applications as the execution layer for a chain via the ABCI (Application Blockchain Interface) protocol. The Cosmos SDK provides a rich set of modules for staking, governance, IBC, and more, and is widely used in the Cosmos ecosystem. This integration allows developers to leverage the full power and flexibility of the Cosmos SDK when building their chain applications. + +- [Cosmos SDK Documentation](https://docs.cosmos.network/) +- [Cosmos SDK ABCI Documentation](https://docs.cosmos.network/main/build/abci/introduction) +- [Evolve ABCI Adapter](https://github.com/evstack/ev-abci) + +### Reth + +Reth is a high-performance Ethereum execution client written in Rust. Evolve can integrate Reth as an execution layer, enabling Ethereum-compatible chains to process EVM transactions and maintain Ethereum-like state. This allows developers to build chains that leverage the Ethereum ecosystem, tooling, and smart contracts, while benefiting from Evolve's modular consensus and data availability. + +For more information about Reth, see the official documentation: + +- [Reth GitHub Repository](https://github.com/paradigmxyz/reth) +- [Evolve Reth Integration](https://github.com/evstack/ev-reth) + +## How It Works + +- Evolve acts as the consensus and uses Celestia as its data availability layer. +- The execution layer (Cosmos SDK app or Reth) processes transactions and maintains application state. + +For more details on integrating an execution layer with Evolve, see the respective documentation links above. diff --git a/docs/learn/sequencing/overview.md b/docs/learn/sequencing/overview.md new file mode 100644 index 0000000000..9f54eb3cf6 --- /dev/null +++ b/docs/learn/sequencing/overview.md @@ -0,0 +1,44 @@ +# Sequencing + + Sequencing is the essential first step for handling your transactions. Think of it as an organizer that takes all incoming transactions, puts them in a clear order, and then groups them into batches. This process is vital for keeping everything consistent and making the chain run. Evolve uses a "Sequencing Interface" with key functions like submitting, retrieving, and verifying these transaction batches, ensuring smooth communication between the chain and the sequencing mechanism, which often acts as a bridge to the underlying network. + +## Sequencing Interface {#sequencing-interface} + +[Sequencing Interface](https://github.com/evstack/ev-node/blob/main/core/sequencer/sequencing.go#L11) defines a sequencing interface for communicating between any sequencing network and Evolve. The key functions of the interface are defined as shown below. + +```go +// Sequencer is a generic interface for a sequencer +type Sequencer interface { + // SubmitBatchTxs submits a batch of transactions from to sequencer + // Id is the unique identifier for the chain + // Batch is the batch of transactions to submit + // returns an error if any from the sequencer + SubmitBatchTxs(ctx context.Context, req SubmitBatchTxsRequest) (*SubmitBatchTxsResponse, error) + + // GetNextBatch returns the next batch of transactions from sequencer to + // Id is the unique identifier for the chain + // LastBatchHash is the cryptographic hash of the last batch received by the + // MaxBytes is the maximum number of bytes to return in the batch + // returns the next batch of transactions and an error if any from the sequencer + GetNextBatch(ctx context.Context, req GetNextBatchRequest) (*GetNextBatchResponse, error) + + // VerifyBatch verifies a batch of transactions received from the sequencer + // Id is the unique identifier for the chain + // BatchHash is the cryptographic hash of the batch to verify + // returns a boolean indicating if the batch is valid and an error if any from the sequencer + VerifyBatch(ctx context.Context, req VerifyBatchResponse) (*VerifyBatchResponse, error) +} +``` + +It mainly consists of: + +* `SubmitBatchTxs` relays the chain transactions from Evolve chain to the sequencing network +* `GetNextBatch` returns the next batch of transactions along with a deterministic timestamp +* `VerifyBatch` validates the sequenced batch + +## Sequencing Implementations {#sequencing-implementations} + +An implementation of the sequencing interface mainly acts as a middleware that connects Evolve chain and the sequencing layer. It implements the sequencing interface functions described above. +There are several implementations of the sequencer but for now only one is available in Evolve. + +* [single-sequencer](/learn/sequencing/single.md) - The simplest and most widely used sequencing model, where a single node (the sequencer) is responsible for ordering transactions and producing blocks. diff --git a/docs/learn/sequencing/single.md b/docs/learn/sequencing/single.md new file mode 100644 index 0000000000..8fbba1730d --- /dev/null +++ b/docs/learn/sequencing/single.md @@ -0,0 +1,49 @@ +# Single Sequencer + +A single sequencer is the simplest sequencing architecture for an Evolve-based chain. In this model, one node (the sequencer) is responsible for ordering transactions, producing blocks, and submitting data to the data availability (DA) layer. + +## How the Single Sequencer Model Works + +1. **Transaction Submission:** + - Users submit transactions to the execution environment via RPC or other interfaces. +2. **Transaction Collection and Ordering:** + - The execution environment collects incoming transactions. + - The sequencer requests a batch of transactions from the execution environment to be included in the next block. +3. **Block Production:** + - **Without lazy mode:** the sequencer produces new blocks at fixed intervals. + - **With lazy mode:** the sequencer produces a block once either + - enough transactions are collected + - the lazy-mode block interval elapses + More info [here](/learn/config#lazy-mode). + - Each block contains a batch of ordered transactions and metadata. + +4. **Data Availability Posting:** + - The sequencer posts the block data to the configured DA layer (e.g., Celestia). + - This ensures that anyone can access the data needed to reconstruct the chain state. + +5. **State Update:** + - The sequencer updates the chain state based on the new block and makes the updated state available to light clients and full nodes. + +## Transaction Flow Diagram + +```mermaid +sequenceDiagram + participant User + participant ExecutionEnv as Execution Environment + participant Sequencer + participant DA as Data Availability Layer + + User->>ExecutionEnv: Submit transaction + Sequencer->>ExecutionEnv: Request batch for block + ExecutionEnv->>Sequencer: Provide batch of transactions + Sequencer->>DA: Post block data + Sequencer->>ExecutionEnv: Update state + ExecutionEnv->>User: State/query response +``` + +## Advantages + +- **Simplicity:** Easy to set up and operate, making it ideal for development, testing, and small-scale deployments compared to other more complex sequencers. +- **Low Latency:** Fast block production and transaction inclusion, since there is no consensus overhead among multiple sequencers. +- **Independence from DA block time:** The sequencer can produce blocks on its own schedule, without being tied to the block time of the DA layer, enabling more flexible transaction processing than DA-timed sequencers. + diff --git a/docs/learn/specs/block-manager.md b/docs/learn/specs/block-manager.md new file mode 100644 index 0000000000..d82dcf22a3 --- /dev/null +++ b/docs/learn/specs/block-manager.md @@ -0,0 +1,599 @@ +# Block Manager + +## Abstract + +The block manager is a key component of full nodes and is responsible for block production or block syncing depending on the node type: sequencer or non-sequencer. Block syncing in this context includes retrieving the published blocks from the network (P2P network or DA network), validating them to raise fraud proofs upon validation failure, updating the state, and storing the validated blocks. A full node invokes multiple block manager functionalities in parallel, such as: + +* Block Production (only for sequencer full nodes) +* Block Publication to DA network +* Block Retrieval from DA network +* Block Sync Service +* Block Publication to P2P network +* Block Retrieval from P2P network +* State Update after Block Retrieval + +```mermaid +sequenceDiagram + title Overview of Block Manager + + participant User + participant Sequencer + participant Full Node 1 + participant Full Node 2 + participant DA Layer + + User->>Sequencer: Send Tx + Sequencer->>Sequencer: Generate Block + Sequencer->>DA Layer: Publish Block + + Sequencer->>Full Node 1: Gossip Block + Sequencer->>Full Node 2: Gossip Block + Full Node 1->>Full Node 1: Verify Block + Full Node 1->>Full Node 2: Gossip Block + Full Node 1->>Full Node 1: Mark Block Soft Confirmed + + Full Node 2->>Full Node 2: Verify Block + Full Node 2->>Full Node 2: Mark Block Soft Confirmed + + DA Layer->>Full Node 1: Retrieve Block + Full Node 1->>Full Node 1: Mark Block DA Included + + DA Layer->>Full Node 2: Retrieve Block + Full Node 2->>Full Node 2: Mark Block DA Included +``` + +### Component Architecture Overview + +```mermaid +flowchart TB + subgraph Block Manager Components + BM[Block Manager] + AGG[Aggregation] + REP[Reaper] + SUB[Submitter] + RET[Retriever] + SYNC[Sync Loop] + DAI[DA Includer] + end + + subgraph External Components + EX[Executor] + SEQ[Sequencer] + DA[DA Layer] + HS[Header Store/P2P] + DS[Data Store/P2P] + ST[Local Store] + end + + REP -->|GetTxs| EX + REP -->|SubmitBatch| SEQ + REP -->|Notify| AGG + + AGG -->|CreateBlock| BM + BM -->|ApplyBlock| EX + BM -->|Save| ST + + BM -->|Headers| SUB + BM -->|Data| SUB + SUB -->|Submit| DA + + RET -->|Retrieve| DA + RET -->|Headers/Data| SYNC + + HS -->|Headers| SYNC + DS -->|Data| SYNC + + SYNC -->|Complete Blocks| BM + SYNC -->|DA Included| DAI + DAI -->|SetFinal| EX +``` + +## Protocol/Component Description + +The block manager is initialized using several parameters as defined below: + +**Name**|**Type**|**Description** +|-----|-----|-----| +signing key|crypto.PrivKey|used for signing blocks and data after creation +config|config.BlockManagerConfig|block manager configurations (see config options below) +genesis|*cmtypes.GenesisDoc|initialize the block manager with genesis state (genesis configuration defined in `config/genesis.json` file under the app directory) +store|store.Store|local datastore for storing chain blocks and states (default local store path is `$db_dir/evolve` and `db_dir` specified in the `config.yaml` file under the app directory) +mempool, proxyapp, eventbus|mempool.Mempool, proxy.AppConnConsensus, *cmtypes.EventBus|for initializing the executor (state transition function). mempool is also used in the manager to check for availability of transactions for lazy block production +dalc|da.DAClient|the data availability light client used to submit and retrieve blocks to DA network +headerStore|*goheaderstore.Store[*types.SignedHeader]|to store and retrieve block headers gossiped over the P2P network +dataStore|*goheaderstore.Store[*types.SignedData]|to store and retrieve block data gossiped over the P2P network +signaturePayloadProvider|types.SignaturePayloadProvider|optional custom provider for header signature payloads +sequencer|core.Sequencer|used to retrieve batches of transactions from the sequencing layer +reaper|*Reaper|component that periodically retrieves transactions from the executor and submits them to the sequencer + +Block manager configuration options: + +|Name|Type|Description| +|-----|-----|-----| +|BlockTime|time.Duration|time interval used for block production and block retrieval from block store ([`defaultBlockTime`][defaultBlockTime])| +|DABlockTime|time.Duration|time interval used for both block publication to DA network and block retrieval from DA network ([`defaultDABlockTime`][defaultDABlockTime])| +|DAStartHeight|uint64|block retrieval from DA network starts from this height| +|LazyBlockInterval|time.Duration|time interval used for block production in lazy aggregator mode even when there are no transactions ([`defaultLazyBlockTime`][defaultLazyBlockTime])| +|LazyMode|bool|when set to true, enables lazy aggregation mode which produces blocks only when transactions are available or at LazyBlockInterval intervals| +|MaxPendingHeadersAndData|uint64|maximum number of pending headers and data blocks before pausing block production (default: 100)| +|GasPrice|float64|gas price for DA submissions (-1 for automatic/default)| +|GasMultiplier|float64|multiplier for gas price on DA submission retries (default: 1.3)| +|Namespace|da.Namespace|DA namespace ID for block submissions| + +### Block Production + +When the full node is operating as a sequencer (aka aggregator), the block manager runs the block production logic. There are two modes of block production, which can be specified in the block manager configurations: `normal` and `lazy`. + +In `normal` mode, the block manager runs a timer, which is set to the `BlockTime` configuration parameter, and continuously produces blocks at `BlockTime` intervals. + +In `lazy` mode, the block manager implements a dual timer mechanism: + +```mermaid +flowchart LR + subgraph Lazy Aggregation Mode + R[Reaper] -->|GetTxs| E[Executor] + E -->|Txs Available| R + R -->|Submit to Sequencer| S[Sequencer] + R -->|NotifyNewTransactions| N[txNotifyCh] + + N --> A{Aggregation Logic} + BT[blockTimer] --> A + LT[lazyTimer] --> A + + A -->|Txs Available| P1[Produce Block with Txs] + A -->|No Txs & LazyTimer| P2[Produce Empty Block] + + P1 --> B[Block Creation] + P2 --> B + end +``` + +1. A `blockTimer` that triggers block production at regular intervals when transactions are available +2. A `lazyTimer` that ensures blocks are produced at `LazyBlockInterval` intervals even during periods of inactivity + +The block manager starts building a block when any transaction becomes available in the mempool via a notification channel (`txNotifyCh`). When the `Reaper` detects new transactions, it calls `Manager.NotifyNewTransactions()`, which performs a non-blocking signal on this channel. The block manager also produces empty blocks at regular intervals to maintain consistency with the DA layer, ensuring a 1:1 mapping between DA layer blocks and execution layer blocks. + +The Reaper component periodically retrieves transactions from the executor and submits them to the sequencer. It runs independently and notifies the block manager when new transactions are available, enabling responsive block production in lazy mode. + +#### Building the Block + +The block manager of the sequencer nodes performs the following steps to produce a block: + +```mermaid +flowchart TD + A[Timer Trigger / Transaction Notification] --> B[Retrieve Batch] + B --> C{Transactions Available?} + C -->|Yes| D[Create Block with Txs] + C -->|No| E[Create Empty Block] + D --> F[Generate Header & Data] + E --> F + F --> G[Sign Header → SignedHeader] + F --> H[Sign Data → SignedData] + G --> I[Apply Block] + H --> I + I --> J[Update State] + J --> K[Save to Store] + K --> L[Add to pendingHeaders] + K --> M[Add to pendingData] + L --> N[Broadcast Header to P2P] + M --> O[Broadcast Data to P2P] +``` + +* Retrieve a batch of transactions using `retrieveBatch()` which interfaces with the sequencer +* Call `CreateBlock` using executor with the retrieved transactions +* Create separate header and data structures from the block +* Sign the header using `signing key` to generate `SignedHeader` +* Sign the data using `signing key` to generate `SignedData` (if transactions exist) +* Call `ApplyBlock` using executor to generate an updated state +* Save the block, validators, and updated state to local store +* Add the newly generated header to `pendingHeaders` queue +* Add the newly generated data to `pendingData` queue (if not empty) +* Publish the newly generated header and data to channels to notify other components of the sequencer node (such as block and header gossip) + +Note: When no transactions are available, the block manager creates blocks with empty data using a special `dataHashForEmptyTxs` marker. The header and data separation architecture allows headers and data to be submitted and retrieved independently from the DA layer. + +### Block Publication to DA Network + +The block manager of the sequencer full nodes implements separate submission loops for headers and data, both operating at `DABlockTime` intervals: + +```mermaid +flowchart LR + subgraph Header Submission + H1[pendingHeaders Queue] --> H2[Header Submission Loop] + H2 --> H3[Marshal to Protobuf] + H3 --> H4[Submit to DA] + H4 -->|Success| H5[Remove from Queue] + H4 -->|Failure| H6[Keep in Queue & Retry] + end + + subgraph Data Submission + D1[pendingData Queue] --> D2[Data Submission Loop] + D2 --> D3[Marshal to Protobuf] + D3 --> D4[Submit to DA] + D4 -->|Success| D5[Remove from Queue] + D4 -->|Failure| D6[Keep in Queue & Retry] + end + + H2 -.->|DABlockTime| H2 + D2 -.->|DABlockTime| D2 +``` + +#### Header Submission Loop + +The `HeaderSubmissionLoop` manages the submission of signed headers to the DA network: + +* Retrieves pending headers from the `pendingHeaders` queue +* Marshals headers to protobuf format +* Submits to DA using the generic `submitToDA` helper +* On success, removes submitted headers from the pending queue +* On failure, headers remain in the queue for retry + +#### Data Submission Loop + +The `DataSubmissionLoop` manages the submission of signed data to the DA network: + +* Retrieves pending data from the `pendingData` queue +* Marshals data to protobuf format +* Submits to DA using the generic `submitToDA` helper +* On success, removes submitted data from the pending queue +* On failure, data remains in the queue for retry + +#### Generic Submission Logic + +Both loops use a shared `submitToDA` function that provides: + +* Retry logic with [`maxSubmitAttempts`][maxSubmitAttempts] attempts +* Exponential backoff starting at [`initialBackoff`][initialBackoff], doubling each attempt, capped at `DABlockTime` +* Gas price management with `GasMultiplier` applied on retries +* Comprehensive metrics tracking for attempts, successes, and failures +* Context-aware cancellation support + +The manager enforces a limit on pending headers and data through `MaxPendingHeadersAndData` configuration. When this limit is reached, block production pauses to prevent unbounded growth of the pending queues. + +### Block Retrieval from DA Network + +The block manager implements a `RetrieveLoop` that regularly pulls headers and data from the DA network: + +```mermaid +flowchart TD + A[Start RetrieveLoop] --> B[Get DA Height] + B --> C{DABlockTime Timer} + C --> D[GetHeightPair from DA] + D --> E{Result?} + E -->|Success| F[Validate Signatures] + E -->|NotFound| G[Increment Height] + E -->|Error| H[Retry Logic] + + F --> I[Check Sequencer Info] + I --> J[Mark DA Included] + J --> K[Send to Sync] + K --> L[Increment Height] + L --> M[Immediate Next Retrieval] + + G --> C + H --> N{Retries < 10?} + N -->|Yes| O[Wait 100ms] + N -->|No| P[Log Error & Stall] + O --> D + M --> D +``` + +#### Retrieval Process + +1. **Height Management**: Starts from the latest of: + * DA height from the last state in local store + * `DAStartHeight` configuration parameter + * Maintains and increments `daHeight` counter after successful retrievals + +2. **Retrieval Mechanism**: + * Executes at `DABlockTime` intervals + * Makes `GetHeightPair(daHeight)` request to get both header and data + * Handles three possible outcomes: + * `Success`: Process retrieved header and data + * `NotFound`: No chain block at this DA height (normal case) + * `Error`: Retry with backoff + +3. **Error Handling**: + * Implements retry logic with 100ms delay between attempts + * After 10 retries, logs error and stalls retrieval + * Does not increment `daHeight` on persistent errors + +4. **Processing Retrieved Blocks**: + * Validates header and data signatures + * Checks sequencer information + * Marks blocks as DA included in caches + * Sends to sync goroutine for state update + * Successful processing triggers immediate next retrieval without waiting for timer + +#### Header and Data Caching + +The retrieval system uses persistent caches for both headers and data: + +* Prevents duplicate processing +* Tracks DA inclusion status +* Supports out-of-order block arrival +* Enables efficient sync from P2P and DA sources + +For more details on DA integration, see the [Data Availability specification](./da.md). + +#### Out-of-Order Chain Blocks on DA + +Evolve should support blocks arriving out-of-order on DA, like so: +![out-of-order blocks](./out-of-order-blocks.png) + +#### Termination Condition + +If the sequencer double-signs two blocks at the same height, evidence of the fault should be posted to DA. Evolve full nodes should process the longest valid chain up to the height of the fault evidence, and terminate. See diagram: +![termination condition](./termination.png) + +### Block Sync Service + +The block sync service manages the synchronization of headers and data through separate stores and channels: + +#### Architecture + +* **Header Store**: Uses `goheader.Store[*types.SignedHeader]` for header management +* **Data Store**: Uses `goheader.Store[*types.SignedData]` for data management +* **Separation of Concerns**: Headers and data are handled independently, supporting the header/data separation architecture + +#### Synchronization Flow + +1. **Header Sync**: Headers created by the sequencer are sent to the header store for P2P gossip +2. **Data Sync**: Data blocks are sent to the data store for P2P gossip +3. **Cache Integration**: Both header and data caches track seen items to prevent duplicates +4. **DA Inclusion Tracking**: Separate tracking for header and data DA inclusion status + +### Block Publication to P2P network + +The sequencer publishes headers and data separately to the P2P network: + +#### Header Publication + +* Headers are sent through the header broadcast channel +* Written to the header store for P2P gossip +* Broadcast to network peers via header sync service + +#### Data Publication + +* Data blocks are sent through the data broadcast channel +* Written to the data store for P2P gossip +* Broadcast to network peers via data sync service + +Non-sequencer full nodes receive headers and data through the P2P sync service and do not publish blocks themselves. + +### Block Retrieval from P2P network + +Non-sequencer full nodes retrieve headers and data separately from P2P stores: + +#### Header Store Retrieval Loop + +The `HeaderStoreRetrieveLoop`: + +* Operates at `BlockTime` intervals via `headerStoreCh` signals +* Tracks `headerStoreHeight` for the last retrieved header +* Retrieves all headers between last height and current store height +* Validates sequencer information using `isUsingExpectedSingleSequencer` +* Marks headers as "seen" in the header cache +* Sends headers to sync goroutine via `headerInCh` + +#### Data Store Retrieval Loop + +The `DataStoreRetrieveLoop`: + +* Operates at `BlockTime` intervals via `dataStoreCh` signals +* Tracks `dataStoreHeight` for the last retrieved data +* Retrieves all data blocks between last height and current store height +* Validates data signatures using `isValidSignedData` +* Marks data as "seen" in the data cache +* Sends data to sync goroutine via `dataInCh` + +#### Soft Confirmations + +Headers and data retrieved from P2P are marked as soft confirmed until both: + +1. The corresponding header is seen on the DA layer +2. The corresponding data is seen on the DA layer + +Once both conditions are met, the block is marked as DA-included. + +#### About Soft Confirmations and DA Inclusions + +The block manager retrieves blocks from both the P2P network and the underlying DA network because the blocks are available in the P2P network faster and DA retrieval is slower (e.g., 1 second vs 6 seconds). +The blocks retrieved from the P2P network are only marked as soft confirmed until the DA retrieval succeeds on those blocks and they are marked DA-included. +DA-included blocks are considered to have a higher level of finality. + +**DAIncluderLoop**: +The `DAIncluderLoop` is responsible for advancing the `DAIncludedHeight` by: + +* Checking if blocks after the current height have both header and data marked as DA-included in caches +* Stopping advancement if either header or data is missing for a height +* Calling `SetFinal` on the executor when a block becomes DA-included +* Storing the Evolve height to DA height mapping for tracking +* Ensuring only blocks with both header and data present are considered DA-included + +### State Update after Block Retrieval + +The block manager uses a `SyncLoop` to coordinate state updates from blocks retrieved via P2P or DA networks: + +```mermaid +flowchart TD + subgraph Sources + P1[P2P Header Store] --> H[headerInCh] + P2[P2P Data Store] --> D[dataInCh] + DA1[DA Header Retrieval] --> H + DA2[DA Data Retrieval] --> D + end + + subgraph SyncLoop + H --> S[Sync Goroutine] + D --> S + S --> C{Header & Data for Same Height?} + C -->|Yes| R[Reconstruct Block] + C -->|No| W[Wait for Matching Pair] + R --> V[Validate Signatures] + V --> A[ApplyBlock] + A --> CM[Commit] + CM --> ST[Store Block & State] + ST --> F{DA Included?} + F -->|Yes| FN[SetFinal] + F -->|No| E[End] + FN --> U[Update DA Height] + end +``` + +#### Sync Loop Architecture + +The `SyncLoop` processes headers and data from multiple sources: + +* Headers from `headerInCh` (P2P and DA sources) +* Data from `dataInCh` (P2P and DA sources) +* Maintains caches to track processed items +* Ensures ordered processing by height + +#### State Update Process + +When both header and data are available for a height: + +1. **Block Reconstruction**: Combines header and data into a complete block +2. **Validation**: Verifies header and data signatures match expectations +3. **ApplyBlock**: + * Validates the block against current state + * Executes transactions + * Captures validator updates + * Returns updated state +4. **Commit**: + * Persists execution results + * Updates mempool by removing included transactions + * Publishes block events +5. **Storage**: + * Stores the block, validators, and updated state + * Updates last state in manager +6. **Finalization**: + * When block is DA-included, calls `SetFinal` on executor + * Updates DA included height + +## Message Structure/Communication Format + +The communication between the block manager and executor: + +* `InitChain`: initializes the chain state with the given genesis time, initial height, and chain ID using `InitChainSync` on the executor to obtain initial `appHash` and initialize the state. +* `CreateBlock`: prepares a block with transactions from the provided batch data. +* `ApplyBlock`: validates the block, executes the block (apply transactions), captures validator updates, and returns updated state. +* `SetFinal`: marks the block as final when both its header and data are confirmed on the DA layer. +* `GetTxs`: retrieves transactions from the application (used by Reaper component). + +The communication with the sequencer: + +* `GetNextBatch`: retrieves the next batch of transactions to include in a block. +* `VerifyBatch`: validates that a batch came from the expected sequencer. + +The communication with DA layer: + +* `Submit`: submits headers or data blobs to the DA network. +* `Get`: retrieves headers or data blobs from the DA network. +* `GetHeightPair`: retrieves both header and data at a specific DA height. + +## Assumptions and Considerations + +* The block manager loads the initial state from the local store and uses genesis if not found in the local store, when the node (re)starts. +* The default mode for sequencer nodes is normal (not lazy). +* The sequencer can produce empty blocks. +* In lazy aggregation mode, the block manager maintains consistency with the DA layer by producing empty blocks at regular intervals, ensuring a 1:1 mapping between DA layer blocks and execution layer blocks. +* The lazy aggregation mechanism uses a dual timer approach: + * A `blockTimer` that triggers block production when transactions are available + * A `lazyTimer` that ensures blocks are produced even during periods of inactivity +* Empty batches are handled differently in lazy mode - instead of discarding them, they are returned with the `ErrNoBatch` error, allowing the caller to create empty blocks with proper timestamps. +* Transaction notifications from the `Reaper` to the `Manager` are handled via a non-blocking notification channel (`txNotifyCh`) to prevent backpressure. +* The block manager enforces `MaxPendingHeadersAndData` limit to prevent unbounded growth of pending queues during DA submission issues. +* Headers and data are submitted separately to the DA layer, supporting the header/data separation architecture. +* The block manager uses persistent caches for headers and data to track seen items and DA inclusion status. +* Gas price management includes automatic adjustment with `GasMultiplier` on DA submission retries. +* The block manager uses persistent storage (disk) when the `root_dir` and `db_path` configuration parameters are specified in `config.yaml` file under the app directory. If these configuration parameters are not specified, the in-memory storage is used, which will not be persistent if the node stops. +* The block manager does not re-apply blocks when they transition from soft confirmed to DA included status. The block is only marked DA included in the caches. +* Header and data stores use separate prefixes for isolation in the underlying database. +* The genesis `ChainID` is used to create separate `PubSubTopID`s for headers and data in go-header. +* Block sync over the P2P network works only when a full node is connected to the P2P network by specifying the initial seeds to connect to via `P2PConfig.Seeds` configuration parameter when starting the full node. +* Node's context is passed down to all components to support graceful shutdown and cancellation. +* The block manager supports custom signature payload providers for headers, enabling flexible signing schemes. +* The block manager supports the separation of header and data structures in Evolve. This allows for expanding the sequencing scheme beyond single sequencing and enables the use of a decentralized sequencer mode. For detailed information on this architecture, see the [Header and Data Separation ADR](../../lazy-adr/adr-014-header-and-data-separation.md). +* The block manager processes blocks with a minimal header format, which is designed to eliminate dependency on CometBFT's header format and can be used to produce an execution layer tailored header if needed. For details on this header structure, see the [Evolve Minimal Header](../../lazy-adr/adr-015-evolve-minimal-header.md) specification. + +## Metrics + +The block manager exposes comprehensive metrics for monitoring: + +### Block Production Metrics + +* `last_block_produced_height`: Height of the last produced block +* `last_block_produced_time`: Timestamp of the last produced block +* `aggregation_type`: Current aggregation mode (normal/lazy) +* `block_size_bytes`: Size distribution of produced blocks +* `produced_empty_blocks_total`: Count of empty blocks produced + +### DA Metrics + +* `da_submission_attempts_total`: Total DA submission attempts +* `da_submission_success_total`: Successful DA submissions +* `da_submission_failure_total`: Failed DA submissions +* `da_retrieval_attempts_total`: Total DA retrieval attempts +* `da_retrieval_success_total`: Successful DA retrievals +* `da_retrieval_failure_total`: Failed DA retrievals +* `da_height`: Current DA retrieval height +* `pending_headers_count`: Number of headers pending DA submission +* `pending_data_count`: Number of data blocks pending DA submission + +### Sync Metrics + +* `sync_height`: Current sync height +* `da_included_height`: Height of last DA-included block +* `soft_confirmed_height`: Height of last soft confirmed block +* `header_store_height`: Current header store height +* `data_store_height`: Current data store height + +### Performance Metrics + +* `block_production_time`: Time to produce a block +* `da_submission_time`: Time to submit to DA +* `state_update_time`: Time to apply block and update state +* `channel_buffer_usage`: Usage of internal channels + +### Error Metrics + +* `errors_total`: Total errors by type and operation + +## Implementation + +See [block-manager] + +See [tutorial] for running a multi-node network with both sequencer and non-sequencer full nodes. + +## References + +[1] [Go Header][go-header] + +[2] [Block Sync][block-sync] + +[3] [Full Node][full-node] + +[4] [Block Manager][block-manager] + +[5] [Tutorial][tutorial] + +[6] [Header and Data Separation ADR](../../lazy-adr/adr-014-header-and-data-separation.md) + +[7] [Evolve Minimal Header](../../lazy-adr/adr-015-evolve-minimal-header.md) + +[8] [Data Availability](./da.md) + +[9] [Lazy Aggregation with DA Layer Consistency ADR](../../lazy-adr/adr-021-lazy-aggregation.md) + +[maxSubmitAttempts]: https://github.com/evstack/ev-node/blob/main/block/manager.go#L50 +[defaultBlockTime]: https://github.com/evstack/ev-node/blob/main/block/manager.go#L36 +[defaultDABlockTime]: https://github.com/evstack/ev-node/blob/main/block/manager.go#L33 +[defaultLazyBlockTime]: https://github.com/evstack/ev-node/blob/main/block/manager.go#L39 +[initialBackoff]: https://github.com/evstack/ev-node/blob/main/block/manager.go#L59 +[go-header]: https://github.com/celestiaorg/go-header +[block-sync]: https://github.com/evstack/ev-node/blob/main/pkg/sync/sync_service.go +[full-node]: https://github.com/evstack/ev-node/blob/main/node/full.go +[block-manager]: https://github.com/evstack/ev-node/blob/main/block/manager.go +[tutorial]: https://ev.xyz/guides/full-node diff --git a/docs/learn/specs/block-validity.md b/docs/learn/specs/block-validity.md new file mode 100644 index 0000000000..a66f59681d --- /dev/null +++ b/docs/learn/specs/block-validity.md @@ -0,0 +1,130 @@ +# Block and Header Validity + +## Abstract + +Like all blockchains, chains are defined as the chain of **valid** blocks from the genesis, to the head. Thus, the block and header validity rules define the chain. + +Verifying a block/header is done in 3 parts: + +1. Verify correct serialization according to the protobuf spec + +2. Perform basic validation of the types + +3. Perform verification of the new block against the previously accepted block + +Evolve uses a header/data separation architecture where headers and data can be validated independently. The system has moved from a multi-validator model to a single signer model for simplified sequencer management. + +## Basic Validation + +Each type contains a `.ValidateBasic()` method, which verifies that certain basic invariants hold. The `ValidateBasic()` calls are nested for each structure. + +### SignedHeader Validation + +```go +SignedHeader.ValidateBasic() + // Make sure the SignedHeader's Header passes basic validation + Header.ValidateBasic() + verify ProposerAddress not nil + // Make sure the SignedHeader's signature passes basic validation + Signature.ValidateBasic() + // Ensure that someone signed the header + verify len(c.Signatures) not 0 + // For based chains (sh.Signer.IsEmpty()), pass validation + if !sh.Signer.IsEmpty(): + // Verify the signer matches the proposer address + verify sh.Signer.Address == sh.ProposerAddress + // Verify signature using custom verifier if set, otherwise use default + if sh.verifier != nil: + verify sh.verifier(sh) == nil + else: + verify sh.Signature.Verify(sh.Signer.PubKey, sh.Header.MarshalBinary()) +``` + +### SignedData Validation + +```go +SignedData.ValidateBasic() + // Always passes basic validation for the Data itself + Data.ValidateBasic() // always passes + // Make sure the signature is valid + Signature.ValidateBasic() + verify len(c.Signatures) not 0 + // Verify the signer + If !sd.Signer.IsEmpty(): + verify sd.Signature.Verify(sd.Signer.PubKey, sd.Data.MarshalBinary()) +``` + +### Block Validation + +Blocks are composed of SignedHeader and Data: + +```go +// Block validation happens by validating header and data separately +// then ensuring data hash matches +verify SignedHeader.ValidateBasic() == nil +verify Data.Hash() == SignedHeader.DataHash +``` + +## Verification Against Previous Block + +```go +SignedHeader.Verify(untrustedHeader *SignedHeader) + // Basic validation is handled by go-header before this + Header.Verify(untrustedHeader) + // Verify height sequence + if untrustedHeader.Height != h.Height + 1: + if untrustedHeader.Height > h.Height + 1: + return soft verification failure + return error "headers are not adjacent" + // Verify the link to previous header + verify untrustedHeader.LastHeaderHash == h.Header.Hash() + // Verify LastCommit hash matches previous signature + verify untrustedHeader.LastCommitHash == sh.Signature.GetCommitHash(...) + // Note: ValidatorHash field exists for compatibility but is not validated +``` + +## [Data](https://github.com/evstack/ev-node/blob/main/types/data.go) + +| **Field Name** | **Valid State** | **Validation** | +|----------------|-----------------------------------------|------------------------------------| +| Txs | Transaction data of the block | Data.Hash() == SignedHeader.DataHash | +| Metadata | Optional p2p gossiping metadata | Not validated | + +## [SignedHeader](https://github.com/evstack/ev-node/blob/main/types/signed_header.go) + +| **Field Name** | **Valid State** | **Validation** | +|----------------|--------------------------------------------------------------------------|---------------------------------------------------------------------------------------------| +| Header | Valid header for the block | `Header` passes `ValidateBasic()` and `Verify()` | +| Signature | Valid signature from the single sequencer | `Signature` passes `ValidateBasic()`, verified against signer | +| Signer | Information about who signed the header | Must match ProposerAddress if not empty (based chain case) | +| verifier | Optional custom signature verification function | Used instead of default verification if set | + +## [Header](https://github.com/evstack/ev-node/blob/main/types/header.go) + +***Note***: Evolve has moved to a single signer model. The multi-validator architecture has been replaced with a simpler single sequencer approach. + +| **Field Name** | **Valid State** | **Validation** | +|---------------------|--------------------------------------------------------------------------------------------|---------------------------------------| +| **BaseHeader** | | | +| Height | Height of the previous accepted header, plus 1. | checked in the `Verify()`` step | +| Time | Timestamp of the block | Not validated in Evolve | +| ChainID | The hard-coded ChainID of the chain | Should be checked as soon as the header is received | +| **Header** . | | | +| Version | unused | | +| LastHeaderHash | The hash of the previous accepted block | checked in the `Verify()`` step | +| LastCommitHash | The hash of the previous accepted block's commit | checked in the `Verify()`` step | +| DataHash | Correct hash of the block's Data field | checked in the `ValidateBasic()`` step | +| ConsensusHash | unused | | +| AppHash | The correct state root after executing the block's transactions against the accepted state | checked during block execution | +| LastResultsHash | Correct results from executing transactions | checked during block execution | +| ProposerAddress | Address of the expected proposer | Must match Signer.Address in SignedHeader | +| ValidatorHash | Compatibility field for Tendermint light client | Not validated | + +## [Signer](https://github.com/evstack/ev-node/blob/main/types/signed_header.go) + +The Signer type replaces the previous ValidatorSet for single sequencer operation: + +| **Field Name** | **Valid State** | **Validation** | +|----------------|-----------------------------------------------------------------|-----------------------------| +| PubKey | Public key of the signer | Must not be nil if Signer is not empty | +| Address | Address derived from the public key | Must match ProposerAddress | diff --git a/docs/learn/specs/da.md b/docs/learn/specs/da.md new file mode 100644 index 0000000000..017e9e35da --- /dev/null +++ b/docs/learn/specs/da.md @@ -0,0 +1,33 @@ +# DA + +Evolve provides a generic [data availability interface][da-interface] for modular blockchains. Any DA that implements this interface can be used with Evolve. + +## Details + +`Client` can connect via JSON-RPC transports using Evolve's [jsonrpc][jsonrpc] implementations. The connection can be configured using the following cli flags: + +* `--evolve.da.address`: url address of the DA service (default: "grpc://localhost:26650") +* `--evolve.da.auth_token`: authentication token of the DA service +* `--evolve.da.namespace`: namespace to use when submitting blobs to the DA service + +Given a set of blocks to be submitted to DA by the block manager, the `SubmitBlocks` first encodes the blocks using protobuf (the encoded data are called blobs) and invokes the `Submit` method on the underlying DA implementation. On successful submission (`StatusSuccess`), the DA block height which included in the blocks is returned. + +To make sure that the serialised blocks don't exceed the underlying DA's blob limits, it fetches the blob size limit by calling `Config` which returns the limit as `uint64` bytes, then includes serialised blocks until the limit is reached. If the limit is reached, it submits the partial set and returns the count of successfully submitted blocks as `SubmittedCount`. The caller should retry with the remaining blocks until all the blocks are submitted. If the first block itself is over the limit, it throws an error. + +The `Submit` call may result in an error (`StatusError`) based on the underlying DA implementations on following scenarios: + +* the total blobs size exceeds the underlying DA's limits (includes empty blobs) +* the implementation specific failures, e.g., for [celestia-da-json-rpc][jsonrpc], invalid namespace, unable to create the commitment or proof, setting low gas price, etc, could return error. + +The `RetrieveBlocks` retrieves the blocks for a given DA height using `GetIDs` and `Get` methods. If there are no blocks available for a given DA height, `StatusNotFound` is returned (which is not an error case). The retrieved blobs are converted back to blocks and returned on successful retrieval. + +Both `SubmitBlocks` and `RetrieveBlocks` may be unsuccessful if the DA node and the DA blockchain that the DA implementation is using have failures. For example, failures such as, DA mempool is full, DA submit transaction is nonce clashing with other transaction from the DA submitter account, DA node is not synced, etc. + +## References + +[1] [da-interface][da-interface] + +[2] [jsonrpc][jsonrpc] + +[da-interface]: https://github.com/evstack/ev-node/blob/main/core/da/da.go#L11 +[jsonrpc]: https://github.com/evstack/ev-node/tree/main/da/jsonrpc diff --git a/docs/learn/specs/full_node.md b/docs/learn/specs/full_node.md new file mode 100644 index 0000000000..638cfe86bb --- /dev/null +++ b/docs/learn/specs/full_node.md @@ -0,0 +1,99 @@ +# Full Node + +## Abstract + +A Full Node is a top-level service that encapsulates different components of Evolve and initializes/manages them. + +## Details + +### Full Node Details + +A Full Node is initialized inside the Cosmos SDK start script along with the node configuration, a private key to use in the P2P client, a private key for signing blocks as a block proposer, a client creator, a genesis document, and a logger. It uses them to initialize the components described above. The components TxIndexer, BlockIndexer, and IndexerService exist to ensure cometBFT compatibility since they are needed for most of the RPC calls from the `SignClient` interface from cometBFT. + +Note that unlike a light node which only syncs and stores block headers seen on the P2P layer, the full node also syncs and stores full blocks seen on both the P2P network and the DA layer. Full blocks contain all the transactions published as part of the block. + +The Full Node mainly encapsulates and initializes/manages the following components: + +### genesisDoc + +The [genesis] document contains information about the initial state of the chain, in particular its validator set. + +### conf + +The [node configuration] contains all the necessary settings for the node to be initialized and function properly. + +### P2P + +The [peer-to-peer client] is used to gossip transactions between full nodes in the network. + +### Store + +The [Store] is initialized with `DefaultStore`, an implementation of the [store interface] which is used for storing and retrieving blocks, commits, and state. | + +### blockManager + +The [Block Manager] is responsible for managing block-related operations including: + +- Block production (normal and lazy modes) +- Header and data submission to DA layer +- Block retrieval and synchronization +- State updates and finalization + +It implements a header/data separation architecture where headers and transaction data are handled independently. + +### dalc + +The [Data Availability Layer Client][dalc] is used to interact with the data availability layer. It is initialized with the DA Layer and DA Config specified in the node configuration. + +### hSyncService + +The [Header Sync Service] is used for syncing signed headers between nodes over P2P. It operates independently from data sync to support light clients. + +### dSyncService + +The [Data Sync Service] is used for syncing transaction data between nodes over P2P. This service is only used by full nodes, not light nodes. + +## Message Structure/Communication Format + +The Full Node communicates with other nodes in the network using the P2P client. It also communicates with the application using the ABCI proxy connections. The communication format is based on the P2P and ABCI protocols. + +## Assumptions and Considerations + +The Full Node assumes that the configuration, private keys, client creator, genesis document, and logger are correctly passed in by the Cosmos SDK. It also assumes that the P2P client, data availability layer client, block manager, and other services can be started and stopped without errors. + +## Implementation + +See [full node] + +## References + +[1] [Full Node][full node] + +[2] [Genesis Document][genesis] + +[3] [Node Configuration][node configuration] + +[4] [Peer to Peer Client][peer-to-peer client] + +[5] [Store][Store] + +[6] [Store Interface][store interface] + +[7] [Block Manager][block manager] + +[8] [Data Availability Layer Client][dalc] + +[9] [Header Sync Service][Header Sync Service] + +[10] [Data Sync Service][Data Sync Service] + +[full node]: https://github.com/evstack/ev-node/blob/main/node/full.go +[genesis]: https://github.com/cometbft/cometbft/blob/main/spec/core/genesis.md +[node configuration]: https://github.com/evstack/ev-node/blob/main/pkg/config/config.go +[peer-to-peer client]: https://github.com/evstack/ev-node/blob/main/pkg/p2p/client.go +[Store]: https://github.com/evstack/ev-node/blob/main/pkg/store/store.go +[store interface]: https://github.com/evstack/ev-node/blob/main/pkg/store/types.go +[Block Manager]: https://github.com/evstack/ev-node/blob/main/block/manager.go +[dalc]: https://github.com/evstack/ev-node/blob/main/core/da/da.go +[Header Sync Service]: https://github.com/evstack/ev-node/blob/main/pkg/sync/sync_service.go +[Data Sync Service]: https://github.com/evstack/ev-node/blob/main/pkg/sync/sync_service.go diff --git a/docs/learn/specs/header-sync.md b/docs/learn/specs/header-sync.md new file mode 100644 index 0000000000..dbda5665da --- /dev/null +++ b/docs/learn/specs/header-sync.md @@ -0,0 +1,109 @@ +# Header and Data Sync + +## Abstract + +The nodes in the P2P network sync headers and data using separate sync services that implement the [go-header][go-header] interface. Evolve uses a header/data separation architecture where headers and transaction data are synchronized independently through parallel services. Each sync service consists of several components as listed below. + +|Component|Description| +|---|---| +|store| a prefixed [datastore][datastore] where synced items are stored (`headerSync` prefix for headers, `dataSync` prefix for data)| +|subscriber| a [libp2p][libp2p] node pubsub subscriber for the specific data type| +|P2P server| a server for handling requests between peers in the P2P network| +|exchange| a client that enables sending in/out-bound requests from/to the P2P network| +|syncer| a service for efficient synchronization. When a P2P node falls behind and wants to catch up to the latest network head via P2P network, it can use the syncer.| + +## Details + +Evolve implements two separate sync services: + +### Header Sync Service + +- Synchronizes `SignedHeader` structures containing block headers with signatures +- Used by all node types (sequencer, full, and light) +- Essential for maintaining the canonical view of the chain + +### Data Sync Service + +- Synchronizes `Data` structures containing transaction data +- Used only by full nodes and sequencers +- Light nodes do not run this service as they only need headers + +Both services: + +- Utilize the generic `SyncService[H header.Header[H]]` implementation +- Inherit the `ConnectionGater` from the node's P2P client for peer management +- Use `NodeConfig.BlockTime` to determine outdated items during sync +- Operate independently on separate P2P topics and datastores + +### Consumption of Sync Services + +#### Header Sync + +- Sequencer nodes publish signed headers to the P2P network after block creation +- Full and light nodes receive and store headers for chain validation +- Headers contain commitments (DataHash) that link to the corresponding data + +#### Data Sync + +- Sequencer nodes publish transaction data separately from headers +- Only full nodes receive and store data (light nodes skip this) +- Data is linked to headers through the DataHash commitment + +#### Parallel Broadcasting + +The block manager broadcasts headers and data in parallel when publishing blocks: + +- Headers are sent through `headerBroadcaster` +- Data is sent through `dataBroadcaster` +- This enables efficient network propagation of both components + +## Assumptions + +- Separate datastores are created with different prefixes: + - Headers: `headerSync` prefix on the main datastore + - Data: `dataSync` prefix on the main datastore +- Network IDs are suffixed to distinguish services: + - Header sync: `{network}-headerSync` + - Data sync: `{network}-dataSync` +- Chain IDs for pubsub topics are also separated: + - Headers: `{chainID}-headerSync` creates topic like `/gm-headerSync/header-sub/v0.0.1` + - Data: `{chainID}-dataSync` creates topic like `/gm-dataSync/header-sub/v0.0.1` +- Both stores must be initialized with genesis items before starting: + - Header store needs genesis header + - Data store needs genesis data (if applicable) +- Genesis items can be loaded via `NodeConfig.TrustedHash` or P2P network query +- Sync services work only when connected to P2P network via `P2PConfig.Seeds` +- Node context is passed to all components for graceful shutdown +- Headers and data are linked through DataHash but synced independently + +## Implementation + +The sync service implementation can be found in [pkg/sync/sync_service.go][sync-service]. The generic `SyncService[H header.Header[H]]` is instantiated as: + +- `HeaderSyncService` for syncing `*types.SignedHeader` +- `DataSyncService` for syncing `*types.Data` + +Full nodes create and start both services, while light nodes only start the header sync service. The services are created in [full][fullnode] and [light][lightnode] node implementations. + +The block manager integrates with both services through: + +- `HeaderStoreRetrieveLoop()` for retrieving headers from P2P +- `DataStoreRetrieveLoop()` for retrieving data from P2P +- Separate broadcast channels for publishing headers and data + +## References + +[1] [Header Sync][sync-service] + +[2] [Full Node][fullnode] + +[3] [Light Node][lightnode] + +[4] [go-header][go-header] + +[sync-service]: https://github.com/evstack/ev-node/blob/main/pkg/sync/sync_service.go +[fullnode]: https://github.com/evstack/ev-node/blob/main/node/full.go +[lightnode]: https://github.com/evstack/ev-node/blob/main/node/light.go +[go-header]: https://github.com/celestiaorg/go-header +[libp2p]: https://github.com/libp2p/go-libp2p +[datastore]: https://github.com/ipfs/go-datastore diff --git a/docs/learn/specs/out-of-order-blocks.png b/docs/learn/specs/out-of-order-blocks.png new file mode 100644 index 0000000000..fa7a955cb9 Binary files /dev/null and b/docs/learn/specs/out-of-order-blocks.png differ diff --git a/docs/learn/specs/overview.md b/docs/learn/specs/overview.md new file mode 100644 index 0000000000..037b06886f --- /dev/null +++ b/docs/learn/specs/overview.md @@ -0,0 +1,17 @@ +# Specs Overview + +Welcome to the Evolve Technical Specifications. + +This is comprehensive documentation on the inner components of Evolve, including data storage, transaction processing, and more. It’s an essential resource for developers looking to understand, contribute to, and leverage the full capabilities of Evolve. + +Each file in this folder covers a specific aspect of the system, from block management to data availability and networking. Use this page as a starting point to explore the technical details and architecture of Evolve. + +## Table of Contents + +- [Block Manager](/learn/specs/block-manager.md): Explains the responsibilities and logic of the block manager in Evolve. +- [Block Validity](/learn/specs/block-validity.md): Details the rules and checks for block validity within the protocol. +- [Data Availability (DA)](/learn/specs/da.md): Describes how Evolve ensures data availability and integrates with DA layers. +- [Full Node](/learn/specs/full_node.md): Outlines the architecture and operation of a full node in Evolve. +- [Header Sync](/learn/specs/header-sync.md): Covers the process and protocol for synchronizing block headers. +- [P2P](/learn/specs/p2p.md): Documents the peer-to-peer networking layer and its protocols. +- [Store](/learn/specs/store.md): Provides information about the storage subsystem and data management. diff --git a/docs/learn/specs/p2p.md b/docs/learn/specs/p2p.md new file mode 100644 index 0000000000..14309d9e3c --- /dev/null +++ b/docs/learn/specs/p2p.md @@ -0,0 +1,60 @@ +# P2P + +Every node (both full and light) runs a P2P client using [go-libp2p][go-libp2p] P2P networking stack for gossiping transactions in the chain's P2P network. The same P2P client is also used by the header and block sync services for gossiping headers and blocks. + +Following parameters are required for creating a new instance of a P2P client: + +* P2PConfig (described below) +* [go-libp2p][go-libp2p] private key used to create a libp2p connection and join the p2p network. +* chainID: identifier used as namespace within the p2p network for peer discovery. The namespace acts as a sub network in the p2p network, where peer connections are limited to the same namespace. +* datastore: an instance of [go-datastore][go-datastore] used for creating a connection gator and stores blocked and allowed peers. +* logger + +```go +// P2PConfig stores configuration related to peer-to-peer networking. +type P2PConfig struct { + ListenAddress string // Address to listen for incoming connections + Seeds string // Comma separated list of seed nodes to connect to + BlockedPeers string // Comma separated list of nodes to ignore + AllowedPeers string // Comma separated list of nodes to whitelist +} +``` + +A P2P client also instantiates a [connection gator][conngater] to block and allow peers specified in the `P2PConfig`. + +It also sets up a gossiper using the gossip topic `+` (`txTopicSuffix` is defined in [p2p/client.go][client.go]), a Distributed Hash Table (DHT) using the `Seeds` defined in the `P2PConfig` and peer discovery using go-libp2p's `discovery.RoutingDiscovery`. + +A P2P client provides an interface `SetTxValidator(p2p.GossipValidator)` for specifying a gossip validator which can define how to handle the incoming `GossipMessage` in the P2P network. The `GossipMessage` represents message gossiped via P2P network (e.g. transaction, Block etc). + +```go +// GossipValidator is a callback function type. +type GossipValidator func(*GossipMessage) bool +``` + +The full nodes define a transaction validator (shown below) as gossip validator for processing the gossiped transactions to add to the mempool, whereas light nodes simply pass a dummy validator as light nodes do not process gossiped transactions. + +```go +// newTxValidator creates a pubsub validator that uses the node's mempool to check the +// transaction. If the transaction is valid, then it is added to the mempool +func (n *FullNode) newTxValidator() p2p.GossipValidator { +``` + +```go +// Dummy validator that always returns a callback function with boolean `false` +func (ln *LightNode) falseValidator() p2p.GossipValidator { +``` + +## References + +[1] [client.go][client.go] + +[2] [go-datastore][go-datastore] + +[3] [go-libp2p][go-libp2p] + +[4] [conngater][conngater] + +[client.go]: https://github.com/evstack/ev-node/blob/main/pkg/p2p/client.go +[go-datastore]: https://github.com/ipfs/go-datastore +[go-libp2p]: https://github.com/libp2p/go-libp2p +[conngater]: https://github.com/libp2p/go-libp2p/tree/master/p2p/net/conngater diff --git a/docs/learn/specs/store.md b/docs/learn/specs/store.md new file mode 100644 index 0000000000..06d671fb2c --- /dev/null +++ b/docs/learn/specs/store.md @@ -0,0 +1,92 @@ +# Store + +## Abstract + +The Store interface defines methods for storing and retrieving blocks, commits, and the state of the blockchain. + +## Protocol/Component Description + +The Store interface defines the following methods: + +- `Height`: Returns the height of the highest block in the store. +- `SetHeight`: Sets given height in the store if it's higher than the existing height in the store. +- `SaveBlock`: Saves a block (containing both header and data) along with its seen signature. +- `GetBlock`: Returns a block at a given height. +- `GetBlockByHash`: Returns a block with a given block header hash. + +Note: While blocks are stored as complete units in the store, the block manager handles headers and data separately during synchronization and DA layer interaction. + +- `SaveBlockResponses`: Saves block responses in the Store. +- `GetBlockResponses`: Returns block results at a given height. +- `GetSignature`: Returns a signature for a block at a given height. +- `GetSignatureByHash`: Returns a signature for a block with a given block header hash. +- `UpdateState`: Updates the state saved in the Store. Only one State is stored. +- `GetState`: Returns the last state saved with UpdateState. +- `SaveValidators`: Saves the validator set at a given height. +- `GetValidators`: Returns the validator set at a given height. + +The `TxnDatastore` interface inside [go-datastore] is used for constructing different key-value stores for the underlying storage of a full node. There are two different implementations of `TxnDatastore` in [kv.go]: + +- `NewDefaultInMemoryKVStore`: Builds a key-value store that uses the [BadgerDB] library and operates in-memory, without accessing the disk. Used only across unit tests and integration tests. + +- `NewDefaultKVStore`: Builds a key-value store that uses the [BadgerDB] library and stores the data on disk at the specified path. + +A Evolve full node is [initialized][full_node_store_initialization] using `NewDefaultKVStore` as the base key-value store for underlying storage. To store various types of data in this base key-value store, different prefixes are used: `mainPrefix`, `dalcPrefix`, and `indexerPrefix`. The `mainPrefix` equal to `0` is used for the main node data, `dalcPrefix` equal to `1` is used for Data Availability Layer Client (DALC) data, and `indexerPrefix` equal to `2` is used for indexing related data. + +For the main node data, `DefaultStore` struct, an implementation of the Store interface, is used with the following prefixes for various types of data within it: + +- `blockPrefix` with value "b": Used to store complete blocks in the key-value store. +- `indexPrefix` with value "i": Used to index the blocks stored in the key-value store. +- `commitPrefix` with value "c": Used to store commits related to the blocks. +- `statePrefix` with value "s": Used to store the state of the blockchain. +- `responsesPrefix` with value "r": Used to store responses related to the blocks. +- `validatorsPrefix` with value "v": Used to store validator sets at a given height. + +Additional prefixes used by sync services: + +- `headerSyncPrefix` with value "hs": Used by the header sync service for P2P synced headers. +- `dataSyncPrefix` with value "ds": Used by the data sync service for P2P synced transaction data. +For example, in a call to `GetBlockByHash` for some block hash ``, the key used in the full node's base key-value store will be `/0/b/` where `0` is the main store prefix and `b` is the block prefix. Similarly, in a call to `GetValidators` for some height ``, the key used in the full node's base key-value store will be `/0/v/` where `0` is the main store prefix and `v` is the validator set prefix. + +Inside the key-value store, the value of these various types of data like `Block` is stored as a byte array which is encoded and decoded using the corresponding Protobuf [marshal and unmarshal methods][serialization]. + +The store is most widely used inside the [block manager] to perform their functions correctly. Within the block manager, since it has multiple go-routines in it, it is protected by a mutex lock, `lastStateMtx`, to synchronize read/write access to it and prevent race conditions. + +## Message Structure/Communication Format + +The Store does not communicate over the network, so there is no message structure or communication format. + +## Assumptions and Considerations + +The Store assumes that the underlying datastore is reliable and provides atomicity for transactions. It also assumes that the data passed to it for storage is valid and correctly formatted. + +## Implementation + +See [Store Interface][store_interface] and [Default Store][default_store] for its implementation. + +## References + +[1] [Store Interface][store_interface] + +[2] [Default Store][default_store] + +[3] [Full Node Store Initialization][full_node_store_initialization] + +[4] [Block Manager][block manager] + +[5] [Badger DB][BadgerDB] + +[6] [Go Datastore][go-datastore] + +[7] [Key Value Store][kv.go] + +[8] [Serialization][serialization] + +[store_interface]: https://github.com/evstack/ev-node/blob/main/pkg/store/types.go#L11 +[default_store]: https://github.com/evstack/ev-node/blob/main/pkg/store/store.go +[full_node_store_initialization]: https://github.com/evstack/ev-node/blob/main/node/full.go#L96 +[block manager]: https://github.com/evstack/ev-node/blob/main/block/manager.go +[BadgerDB]: https://github.com/dgraph-io/badger +[go-datastore]: https://github.com/ipfs/go-datastore +[kv.go]: https://github.com/evstack/ev-node/blob/main/pkg/store/kv.go +[serialization]: https://github.com/evstack/ev-node/blob/main/types/serialization.go diff --git a/docs/learn/specs/template.md b/docs/learn/specs/template.md new file mode 100644 index 0000000000..6471abe7b8 --- /dev/null +++ b/docs/learn/specs/template.md @@ -0,0 +1,103 @@ +# Protocol/Component Name + +## Abstract + +Provide a concise description of the purpose of the component for which the +specification is written, along with its contribution to the evolve or +other relevant parts of the system. Make sure to include proper references to +the relevant sections. + +## Protocol/Component Description + +Offer a comprehensive explanation of the protocol, covering aspects such as data +flow, communication mechanisms, and any other details necessary for +understanding the inner workings of this component. + +## Message Structure/Communication Format + +If this particular component is expected to communicate over the network, +outline the structure of the message protocol, including details such as field +interpretation, message format, and any other relevant information. + +## Assumptions and Considerations + +If there are any assumptions required for the component's correct operation, +performance, security, or other expected features, outline them here. +Additionally, provide any relevant considerations related to security or other +concerns. + +## Implementation + +Include a link to the location where the implementation of this protocol can be +found. Note that specific implementation details should be documented in the +evolve repository rather than in the specification document. + +## References + +List any references used or cited in the document. + +## General Tips + +### How to use a mermaid diagram that you can display in a markdown + +```mermaid + +sequenceDiagram + title Example + participant A + participant B + A->>B: Example + B->>A: Example + + ``` + + ```mermaid + +graph LR + A[Example] --> B[Example] + B --> C[Example] + C --> A + + ``` + + ```mermaid + +gantt + title Example + dateFormat YYYY-MM-DD + section Example + A :done, des1, 2014-01-06,2014-01-08 + B :done, des2, 2014-01-06,2014-01-08 + C :done, des3, 2014-01-06,2014-01-08 + + ``` + +### Grammar and spelling check + +The recommendation is to use your favorite spellchecker extension in your IDE like [grammarly], to make sure that the document is free of spelling and grammar errors. + +### Use of links + +If you want to use links use proper syntax. This goes for both internal and external links like [documentation] or [external links] + +At the bottom of the document in the [References](#references) section, you can add the following footnotes that will be visible in the markdown document: + +[1] [Grammarly][grammarly] + +[2] [Documentation][documentation] + +[3] [external links][external links] + +Then at the bottom add the actual links that will not be visible in the markdown document: + +[grammarly]: https://www.grammarly.com/ +[documentation]: ../README.md +[external links]: https://github.com/celestiaorg/go-header + +### Use of tables + +If you are describing variables, components or other things in a structured list that can be described in a table use the following syntax: + +| Name | Type | Description | +| ---- | ---- | ----------- | +| `name` | `type` | Description | diff --git a/docs/learn/specs/termination.png b/docs/learn/specs/termination.png new file mode 100644 index 0000000000..0b61c8f232 Binary files /dev/null and b/docs/learn/specs/termination.png differ diff --git a/docs/learn/transaction-flow.md b/docs/learn/transaction-flow.md new file mode 100644 index 0000000000..23320784e2 --- /dev/null +++ b/docs/learn/transaction-flow.md @@ -0,0 +1,53 @@ +# Transaction flow + +Chain users use a light node to communicate with the chain P2P network for two primary reasons: + +- submitting transactions +- gossipping headers and fraud proofs + +Here's what the typical transaction flow looks like: + +## Transaction submission + +```mermaid +sequenceDiagram + participant User + participant LightNode + participant FullNode + + User->>LightNode: Submit Transaction + LightNode->>FullNode: Gossip Transaction + FullNode-->>User: Refuse (if invalid) +``` + +## Transaction validation and processing + +```mermaid +sequenceDiagram + participant FullNode + participant Sequencer + + FullNode->>FullNode: Check Validity + FullNode->>FullNode: Add to Mempool (if valid) + FullNode-->>User: Transaction Processed (if valid) + FullNode->>Sequencer: Inform about Valid Transaction + Sequencer->>DALayer: Add to Chain Block +``` + +## Block processing + +```mermaid +sequenceDiagram + participant DALayer + participant FullNode + participant Chain + + DALayer->>Chain: Update State + DALayer->>FullNode: Download & Validate Block +``` + +To transact, users submit a transaction to their light node, which gossips the transaction to a full node. Before adding the transaction to their mempool, the full node checks its validity. Valid transactions are included in the mempool, while invalid ones are refused, and the user's transaction will not be processed. + +If the transaction is valid and has been included in the mempool, the sequencer can add it to a chain block, which is then submitted to the data availability (DA) layer. This results in a successful transaction flow for the user, and the state of the chain is updated accordingly. + +After the block is submitted to the DA layer, the full nodes download and validate the block. diff --git a/docs/package.json b/docs/package.json new file mode 100644 index 0000000000..74960eed05 --- /dev/null +++ b/docs/package.json @@ -0,0 +1,20 @@ +{ + "name": "evolve-docs", + "version": "1.0.0", + "license": "MIT", + "scripts": { + "dev": "vitepress dev", + "build": "vitepress build", + "preview": "vitepress preview" + }, + "devDependencies": { + "mermaid": "^11.8.1", + "terser": "^5.43.1", + "vitepress": "^1.5.0", + "vitepress-plugin-mermaid": "^2.0.17" + }, + "dependencies": { + "vitepress-openapi": "^0.1.3" + }, + "type": "module" +} diff --git a/docs/public/img/color-scheme.png b/docs/public/img/color-scheme.png new file mode 100644 index 0000000000..70ce555b60 Binary files /dev/null and b/docs/public/img/color-scheme.png differ diff --git a/docs/public/img/evolve-mascot.png b/docs/public/img/evolve-mascot.png new file mode 100644 index 0000000000..b91d4ad388 Binary files /dev/null and b/docs/public/img/evolve-mascot.png differ diff --git a/docs/public/img/favicon.ico b/docs/public/img/favicon.ico new file mode 100644 index 0000000000..4ffbf0b381 Binary files /dev/null and b/docs/public/img/favicon.ico differ diff --git a/docs/public/img/favicon.png b/docs/public/img/favicon.png new file mode 100644 index 0000000000..b91d4ad388 Binary files /dev/null and b/docs/public/img/favicon.png differ diff --git a/docs/public/img/favicon.svg b/docs/public/img/favicon.svg new file mode 100644 index 0000000000..0e912b6a74 --- /dev/null +++ b/docs/public/img/favicon.svg @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/public/img/logo.png b/docs/public/img/logo.png new file mode 100644 index 0000000000..d06787f97b Binary files /dev/null and b/docs/public/img/logo.png differ diff --git a/docs/src/openapi-rpc.json b/docs/src/openapi-rpc.json new file mode 100644 index 0000000000..851689590f --- /dev/null +++ b/docs/src/openapi-rpc.json @@ -0,0 +1,967 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "Rollkit API", + "description": "This API provides access to Signer, Store, P2P, and Health services.\n\n## Services\n\n* **Signer Service** - Sign messages and retrieve public keys\n* **Store Service** - Access blocks, state, and metadata\n* **P2P Service** - Network and peer information\n* **Health Service** - Node health checks and simple HTTP endpoints\n\n## Protocols\n\n### gRPC-Web Protocol\n\nMost endpoints use gRPC-Web protocol over HTTP/1.1 with JSON encoding. Requests are made via POST with `Content-Type: application/json`.\n\n### Simple HTTP Endpoints\n\nSome endpoints (like `/health/live`) are simple HTTP GET requests that return plain text responses for basic monitoring and health checks.", + "version": "1.0.0", + "contact": { + "name": "Rollkit Team", + "url": "https://rollkit.dev" + } + }, + "servers": [ + { + "url": "http://localhost:7331", + "description": "A local Rollkit instance configured to provide a remote procedure call (RPC) endpoint, actively listening for connections on TCP port 7331." + } + ], + "tags": [ + { + "name": "Signer Service", + "description": "Sign messages and retrieve public keys" + }, + { + "name": "Store Service", + "description": "Access blocks, state, and metadata from the chain store" + }, + { + "name": "P2P Service", + "description": "Network and peer information" + }, + { + "name": "Health Service", + "description": "Node health and liveness checks" + } + ], + "paths": { + "/evnode.v1.SignerService/Sign": { + "post": { + "tags": [ + "Signer Service" + ], + "summary": "Sign a message", + "description": "Sign the given message bytes and return the signature.", + "operationId": "sign", + "requestBody": { + "description": "Message to sign", + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SignRequest" + }, + "examples": { + "default": { + "summary": "Sign a message", + "value": { + "message": "SGVsbG8gV29ybGQ=" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Message signed successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SignResponse" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + } + } + }, + "/evnode.v1.SignerService/GetPublic": { + "post": { + "tags": [ + "Signer Service" + ], + "summary": "Get public key", + "description": "Retrieve the public key of the signer.", + "operationId": "getPublic", + "requestBody": { + "description": "Get public key request (empty)", + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetPublicRequest" + }, + "examples": { + "default": { + "summary": "Get public key", + "value": {} + } + } + } + } + }, + "responses": { + "200": { + "description": "Public key retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetPublicResponse" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + } + } + }, + "/evnode.v1.StoreService/GetBlock": { + "post": { + "tags": [ + "Store Service" + ], + "summary": "Get a block", + "description": "Retrieve a block by height or hash from the chain store.", + "operationId": "getBlock", + "requestBody": { + "description": "Block request parameters", + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetBlockRequest" + }, + "examples": { + "by_height": { + "summary": "Get block by height", + "value": { + "height": 1 + } + }, + "by_hash": { + "summary": "Get block by hash", + "value": { + "hash": "SGVsbG8gV29ybGQ=" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Block retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetBlockResponse" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + } + } + }, + "/evnode.v1.StoreService/GetState": { + "post": { + "tags": [ + "Store Service" + ], + "summary": "Get current state", + "description": "Retrieve the current state of the chain.", + "operationId": "getState", + "requestBody": { + "description": "State request (empty)", + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetStateRequest" + }, + "examples": { + "default": { + "summary": "Get current state", + "value": {} + } + } + } + } + }, + "responses": { + "200": { + "description": "State retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetStateResponse" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + } + } + }, + "/evnode.v1.StoreService/GetMetadata": { + "post": { + "tags": [ + "Store Service" + ], + "summary": "Get metadata", + "description": "Retrieve metadata by key from the chain store.", + "operationId": "getMetadata", + "requestBody": { + "description": "Metadata request with key", + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetMetadataRequest" + }, + "examples": { + "default": { + "summary": "Get metadata by key", + "value": { + "key": "example_key" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Metadata retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetMetadataResponse" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + } + } + }, + "/evnode.v1.P2PService/GetPeerInfo": { + "post": { + "tags": [ + "P2P Service" + ], + "summary": "Get peer information", + "description": "Retrieve information about connected peers.", + "operationId": "getPeerInfo", + "requestBody": { + "description": "Peer info request (empty)", + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetPeerInfoRequest" + }, + "examples": { + "default": { + "summary": "Get peer information", + "value": {} + } + } + } + } + }, + "responses": { + "200": { + "description": "Peer information retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetPeerInfoResponse" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + } + } + }, + "/evnode.v1.P2PService/GetNetInfo": { + "post": { + "tags": [ + "P2P Service" + ], + "summary": "Get network information", + "description": "Retrieve network information and statistics.", + "operationId": "getNetInfo", + "requestBody": { + "description": "Network info request (empty)", + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetNetInfoRequest" + }, + "examples": { + "default": { + "summary": "Get network information", + "value": {} + } + } + } + } + }, + "responses": { + "200": { + "description": "Network information retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetNetInfoResponse" + } + } + } + }, + "500": { + "$ref": "#/components/responses/InternalError" + } + } + } + }, + "/evnode.v1.HealthService/Livez": { + "post": { + "tags": [ + "Health Service" + ], + "summary": "Check node health", + "description": "Check if the node is alive and healthy.", + "operationId": "livez", + "requestBody": { + "description": "Health check request (empty)", + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LivezRequest" + }, + "examples": { + "default": { + "summary": "Check node health", + "value": {} + } + } + } + } + }, + "responses": { + "200": { + "description": "Node is healthy", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetHealthResponse" + } + } + } + }, + "503": { + "description": "Node is unhealthy", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/health/live": { + "get": { + "tags": [ + "Health Service" + ], + "summary": "Simple liveness check", + "description": "Simple HTTP endpoint to check if the node is alive. Returns plain text 'OK' response.", + "operationId": "healthLive", + "responses": { + "200": { + "description": "Node is alive", + "content": { + "text/plain": { + "schema": { + "type": "string", + "example": "OK" + } + } + } + } + } + } + } + }, + "components": { + "responses": { + "BadRequest": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "NotFound": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "InternalError": { + "description": "Internal Server Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "schemas": { + "SignRequest": { + "type": "object", + "description": "Request to sign a message", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string", + "format": "byte", + "description": "The bytes we want to sign (base64-encoded)", + "example": "SGVsbG8gV29ybGQ=" + } + } + }, + "SignResponse": { + "type": "object", + "description": "Response containing signature", + "required": [ + "signature" + ], + "properties": { + "signature": { + "type": "string", + "format": "byte", + "description": "The signature bytes (base64-encoded)", + "example": "c2lnbmF0dXJl" + } + } + }, + "GetPublicRequest": { + "type": "object", + "description": "Request to get public key (empty)", + "properties": {} + }, + "GetPublicResponse": { + "type": "object", + "description": "Response containing public key", + "required": [ + "public_key" + ], + "properties": { + "public_key": { + "type": "string", + "format": "byte", + "description": "The public key (base64-encoded)", + "example": "cHVibGljX2tleQ==" + } + } + }, + "GetBlockRequest": { + "type": "object", + "description": "Request to get a block by height or hash", + "properties": { + "height": { + "type": "integer", + "format": "int64", + "description": "Block height to retrieve", + "example": 1 + }, + "hash": { + "type": "string", + "format": "byte", + "description": "Block hash to retrieve (base64-encoded)", + "example": "SGVsbG8gV29ybGQ=" + } + } + }, + "GetBlockResponse": { + "type": "object", + "description": "Response containing block data", + "properties": { + "block": { + "$ref": "#/components/schemas/Block" + }, + "header_da_height": { + "type": "integer", + "format": "int64", + "description": "Data availability height for header" + }, + "data_da_height": { + "type": "integer", + "format": "int64", + "description": "Data availability height for data" + } + } + }, + "GetStateRequest": { + "type": "object", + "description": "Request to get current state (empty)", + "properties": {} + }, + "GetStateResponse": { + "type": "object", + "description": "Response containing current state", + "properties": { + "state": { + "$ref": "#/components/schemas/State" + } + } + }, + "GetMetadataRequest": { + "type": "object", + "description": "Request to get metadata by key", + "required": [ + "key" + ], + "properties": { + "key": { + "type": "string", + "description": "Metadata key to retrieve", + "example": "example_key" + } + } + }, + "GetMetadataResponse": { + "type": "object", + "description": "Response containing metadata", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "string", + "format": "byte", + "description": "Metadata value (base64-encoded)", + "example": "dGVzdCB2YWx1ZQ==" + } + } + }, + "GetPeerInfoRequest": { + "type": "object", + "description": "Request to get peer information (empty)", + "properties": {} + }, + "GetPeerInfoResponse": { + "type": "object", + "description": "Response containing peer information", + "required": [ + "peers" + ], + "properties": { + "peers": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PeerInfo" + }, + "description": "List of connected peers" + } + } + }, + "GetNetInfoRequest": { + "type": "object", + "description": "Request to get network information (empty)", + "properties": {} + }, + "GetNetInfoResponse": { + "type": "object", + "description": "Response containing network information", + "properties": { + "net_info": { + "$ref": "#/components/schemas/NetInfo" + } + } + }, + "LivezRequest": { + "type": "object", + "description": "Request to check node health (empty)", + "properties": {} + }, + "GetHealthResponse": { + "type": "object", + "description": "Response indicating node health status", + "required": [ + "status" + ], + "properties": { + "status": { + "$ref": "#/components/schemas/HealthStatus" + } + } + }, + "HealthStatus": { + "type": "string", + "enum": [ + "UNKNOWN", + "PASS", + "WARN", + "FAIL" + ], + "description": "Health status of the node" + }, + "Block": { + "type": "object", + "description": "Chain block data", + "properties": { + "header": { + "$ref": "#/components/schemas/SignedHeader" + }, + "data": { + "$ref": "#/components/schemas/Data" + } + } + }, + "SignedHeader": { + "type": "object", + "description": "Signed block header", + "properties": { + "header": { + "$ref": "#/components/schemas/Header" + }, + "signature": { + "type": "string", + "format": "byte", + "description": "Header signature (base64-encoded)" + }, + "signer": { + "$ref": "#/components/schemas/Signer" + } + } + }, + "Header": { + "type": "object", + "description": "Block header information", + "required": [ + "height", + "time", + "chain_id" + ], + "properties": { + "version": { + "$ref": "#/components/schemas/Version" + }, + "height": { + "type": "integer", + "format": "int64", + "description": "Block height" + }, + "time": { + "type": "integer", + "format": "int64", + "description": "Block creation time" + }, + "last_header_hash": { + "type": "string", + "format": "byte", + "description": "Previous block info (base64-encoded)" + }, + "last_commit_hash": { + "type": "string", + "format": "byte", + "description": "Commit from aggregator(s) from the last block (base64-encoded)" + }, + "data_hash": { + "type": "string", + "format": "byte", + "description": "Block.Data root aka Transactions (base64-encoded)" + }, + "consensus_hash": { + "type": "string", + "format": "byte", + "description": "Consensus params for current block (base64-encoded)" + }, + "app_hash": { + "type": "string", + "format": "byte", + "description": "State after applying txs from the current block (base64-encoded)" + }, + "last_results_hash": { + "type": "string", + "format": "byte", + "description": "Root hash of all results from the txs from the previous block (base64-encoded)" + }, + "proposer_address": { + "type": "string", + "format": "byte", + "description": "Original proposer of the block (base64-encoded)" + }, + "validator_hash": { + "type": "string", + "format": "byte", + "description": "validatorhash for compatibility with tendermint light client (base64-encoded)" + }, + "chain_id": { + "type": "string", + "description": "Chain ID the block belongs to" + } + } + }, + "Version": { + "type": "object", + "description": "Version captures the consensus rules for processing a block", + "required": [ + "block", + "app" + ], + "properties": { + "block": { + "type": "integer", + "format": "int64", + "description": "Block version" + }, + "app": { + "type": "integer", + "format": "int64", + "description": "App version" + } + } + }, + "Signer": { + "type": "object", + "description": "Signer of a block", + "required": [ + "address", + "pub_key" + ], + "properties": { + "address": { + "type": "string", + "format": "byte", + "description": "Address of the signer (base64-encoded)" + }, + "pub_key": { + "type": "string", + "format": "byte", + "description": "Public key of the signer (base64-encoded)" + } + } + }, + "Data": { + "type": "object", + "description": "Block transaction data", + "required": [ + "txs" + ], + "properties": { + "metadata": { + "$ref": "#/components/schemas/Metadata" + }, + "txs": { + "type": "array", + "items": { + "type": "string", + "format": "byte" + }, + "description": "List of transactions (base64-encoded)" + } + } + }, + "Metadata": { + "type": "object", + "description": "Metadata of a block", + "required": [ + "chain_id", + "height", + "time" + ], + "properties": { + "chain_id": { + "type": "string", + "description": "Chain ID" + }, + "height": { + "type": "integer", + "format": "int64", + "description": "Block height" + }, + "time": { + "type": "integer", + "format": "int64", + "description": "Block creation time" + }, + "last_data_hash": { + "type": "string", + "format": "byte", + "description": "Previous block info (base64-encoded)" + } + } + }, + "State": { + "type": "object", + "description": "Current chain state", + "required": [ + "chain_id", + "initial_height", + "last_block_height", + "da_height" + ], + "properties": { + "version": { + "$ref": "#/components/schemas/Version" + }, + "chain_id": { + "type": "string", + "description": "Chain ID" + }, + "initial_height": { + "type": "integer", + "format": "int64", + "description": "Initial height" + }, + "last_block_height": { + "type": "integer", + "format": "int64", + "description": "Last block height" + }, + "last_block_time": { + "type": "string", + "format": "date-time", + "description": "Last block time" + }, + "da_height": { + "type": "integer", + "format": "int64", + "description": "Data availability height" + }, + "last_results_hash": { + "type": "string", + "format": "byte", + "description": "Last results hash (base64-encoded)" + }, + "app_hash": { + "type": "string", + "format": "byte", + "description": "Application state hash (base64-encoded)" + } + } + }, + "PeerInfo": { + "type": "object", + "description": "Information about a connected peer", + "required": [ + "id", + "address" + ], + "properties": { + "id": { + "type": "string", + "description": "Peer ID" + }, + "address": { + "type": "string", + "description": "Peer network address" + } + } + }, + "NetInfo": { + "type": "object", + "description": "Network information", + "required": [ + "id", + "listen_addresses", + "connected_peers" + ], + "properties": { + "id": { + "type": "string", + "description": "Network ID" + }, + "listen_addresses": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Listen addresses" + }, + "connected_peers": { + "type": "array", + "items": { + "type": "string" + }, + "description": "List of connected peers" + } + } + }, + "Error": { + "type": "object", + "description": "Error response", + "required": [ + "code", + "message" + ], + "properties": { + "code": { + "type": "integer", + "description": "Error code" + }, + "message": { + "type": "string", + "description": "Error message" + }, + "details": { + "type": "array", + "items": { + "type": "object" + }, + "description": "Additional error details" + } + } + } + } + } +} diff --git a/docs/yarn.lock b/docs/yarn.lock new file mode 100644 index 0000000000..817569dfd0 --- /dev/null +++ b/docs/yarn.lock @@ -0,0 +1,2486 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@algolia/autocomplete-core@1.9.3": + version "1.9.3" + resolved "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz" + integrity sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw== + dependencies: + "@algolia/autocomplete-plugin-algolia-insights" "1.9.3" + "@algolia/autocomplete-shared" "1.9.3" + +"@algolia/autocomplete-plugin-algolia-insights@1.9.3": + version "1.9.3" + resolved "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz" + integrity sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg== + dependencies: + "@algolia/autocomplete-shared" "1.9.3" + +"@algolia/autocomplete-preset-algolia@1.9.3": + version "1.9.3" + resolved "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.3.tgz" + integrity sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA== + dependencies: + "@algolia/autocomplete-shared" "1.9.3" + +"@algolia/autocomplete-shared@1.9.3": + version "1.9.3" + resolved "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz" + integrity sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ== + +"@algolia/cache-browser-local-storage@4.24.0": + version "4.24.0" + resolved "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.24.0.tgz" + integrity sha512-t63W9BnoXVrGy9iYHBgObNXqYXM3tYXCjDSHeNwnsc324r4o5UiVKUiAB4THQ5z9U5hTj6qUvwg/Ez43ZD85ww== + dependencies: + "@algolia/cache-common" "4.24.0" + +"@algolia/cache-common@4.24.0": + version "4.24.0" + resolved "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.24.0.tgz" + integrity sha512-emi+v+DmVLpMGhp0V9q9h5CdkURsNmFC+cOS6uK9ndeJm9J4TiqSvPYVu+THUP8P/S08rxf5x2P+p3CfID0Y4g== + +"@algolia/cache-in-memory@4.24.0": + version "4.24.0" + resolved "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.24.0.tgz" + integrity sha512-gDrt2so19jW26jY3/MkFg5mEypFIPbPoXsQGQWAi6TrCPsNOSEYepBMPlucqWigsmEy/prp5ug2jy/N3PVG/8w== + dependencies: + "@algolia/cache-common" "4.24.0" + +"@algolia/client-account@4.24.0": + version "4.24.0" + resolved "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.24.0.tgz" + integrity sha512-adcvyJ3KjPZFDybxlqnf+5KgxJtBjwTPTeyG2aOyoJvx0Y8dUQAEOEVOJ/GBxX0WWNbmaSrhDURMhc+QeevDsA== + dependencies: + "@algolia/client-common" "4.24.0" + "@algolia/client-search" "4.24.0" + "@algolia/transporter" "4.24.0" + +"@algolia/client-analytics@4.24.0": + version "4.24.0" + resolved "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.24.0.tgz" + integrity sha512-y8jOZt1OjwWU4N2qr8G4AxXAzaa8DBvyHTWlHzX/7Me1LX8OayfgHexqrsL4vSBcoMmVw2XnVW9MhL+Y2ZDJXg== + dependencies: + "@algolia/client-common" "4.24.0" + "@algolia/client-search" "4.24.0" + "@algolia/requester-common" "4.24.0" + "@algolia/transporter" "4.24.0" + +"@algolia/client-common@4.24.0": + version "4.24.0" + resolved "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz" + integrity sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA== + dependencies: + "@algolia/requester-common" "4.24.0" + "@algolia/transporter" "4.24.0" + +"@algolia/client-personalization@4.24.0": + version "4.24.0" + resolved "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.24.0.tgz" + integrity sha512-l5FRFm/yngztweU0HdUzz1rC4yoWCFo3IF+dVIVTfEPg906eZg5BOd1k0K6rZx5JzyyoP4LdmOikfkfGsKVE9w== + dependencies: + "@algolia/client-common" "4.24.0" + "@algolia/requester-common" "4.24.0" + "@algolia/transporter" "4.24.0" + +"@algolia/client-search@4.24.0": + version "4.24.0" + resolved "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz" + integrity sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA== + dependencies: + "@algolia/client-common" "4.24.0" + "@algolia/requester-common" "4.24.0" + "@algolia/transporter" "4.24.0" + +"@algolia/logger-common@4.24.0": + version "4.24.0" + resolved "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.24.0.tgz" + integrity sha512-LLUNjkahj9KtKYrQhFKCzMx0BY3RnNP4FEtO+sBybCjJ73E8jNdaKJ/Dd8A/VA4imVHP5tADZ8pn5B8Ga/wTMA== + +"@algolia/logger-console@4.24.0": + version "4.24.0" + resolved "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.24.0.tgz" + integrity sha512-X4C8IoHgHfiUROfoRCV+lzSy+LHMgkoEEU1BbKcsfnV0i0S20zyy0NLww9dwVHUWNfPPxdMU+/wKmLGYf96yTg== + dependencies: + "@algolia/logger-common" "4.24.0" + +"@algolia/recommend@4.24.0": + version "4.24.0" + resolved "https://registry.npmjs.org/@algolia/recommend/-/recommend-4.24.0.tgz" + integrity sha512-P9kcgerfVBpfYHDfVZDvvdJv0lEoCvzNlOy2nykyt5bK8TyieYyiD0lguIJdRZZYGre03WIAFf14pgE+V+IBlw== + dependencies: + "@algolia/cache-browser-local-storage" "4.24.0" + "@algolia/cache-common" "4.24.0" + "@algolia/cache-in-memory" "4.24.0" + "@algolia/client-common" "4.24.0" + "@algolia/client-search" "4.24.0" + "@algolia/logger-common" "4.24.0" + "@algolia/logger-console" "4.24.0" + "@algolia/requester-browser-xhr" "4.24.0" + "@algolia/requester-common" "4.24.0" + "@algolia/requester-node-http" "4.24.0" + "@algolia/transporter" "4.24.0" + +"@algolia/requester-browser-xhr@4.24.0": + version "4.24.0" + resolved "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.24.0.tgz" + integrity sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA== + dependencies: + "@algolia/requester-common" "4.24.0" + +"@algolia/requester-common@4.24.0": + version "4.24.0" + resolved "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.24.0.tgz" + integrity sha512-k3CXJ2OVnvgE3HMwcojpvY6d9kgKMPRxs/kVohrwF5WMr2fnqojnycZkxPoEg+bXm8fi5BBfFmOqgYztRtHsQA== + +"@algolia/requester-node-http@4.24.0": + version "4.24.0" + resolved "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.24.0.tgz" + integrity sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw== + dependencies: + "@algolia/requester-common" "4.24.0" + +"@algolia/transporter@4.24.0": + version "4.24.0" + resolved "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.24.0.tgz" + integrity sha512-86nI7w6NzWxd1Zp9q3413dRshDqAzSbsQjhcDhPIatEFiZrL1/TjnHL8S7jVKFePlIMzDsZWXAXwXzcok9c5oA== + dependencies: + "@algolia/cache-common" "4.24.0" + "@algolia/logger-common" "4.24.0" + "@algolia/requester-common" "4.24.0" + +"@antfu/install-pkg@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@antfu/install-pkg/-/install-pkg-1.1.0.tgz#78fa036be1a6081b5a77a5cf59f50c7752b6ba26" + integrity sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ== + dependencies: + package-manager-detector "^1.3.0" + tinyexec "^1.0.1" + +"@antfu/utils@^8.1.0": + version "8.1.1" + resolved "https://registry.yarnpkg.com/@antfu/utils/-/utils-8.1.1.tgz#95b1947d292a9a2efffba2081796dcaa05ecedfb" + integrity sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ== + +"@babel/helper-string-parser@^7.24.8": + version "7.24.8" + resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz" + integrity sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ== + +"@babel/helper-string-parser@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz#54da796097ab19ce67ed9f88b47bb2ec49367687" + integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA== + +"@babel/helper-validator-identifier@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz" + integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w== + +"@babel/helper-validator-identifier@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz#a7054dcc145a967dd4dc8fee845a57c1316c9df8" + integrity sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow== + +"@babel/parser@^7.25.3": + version "7.25.6" + resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz" + integrity sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q== + dependencies: + "@babel/types" "^7.25.6" + +"@babel/parser@^7.28.0": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.0.tgz#979829fbab51a29e13901e5a80713dbcb840825e" + integrity sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g== + dependencies: + "@babel/types" "^7.28.0" + +"@babel/types@^7.25.6": + version "7.25.6" + resolved "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz" + integrity sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw== + dependencies: + "@babel/helper-string-parser" "^7.24.8" + "@babel/helper-validator-identifier" "^7.24.7" + to-fast-properties "^2.0.0" + +"@babel/types@^7.28.0": + version "7.28.1" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.1.tgz#2aaf3c10b31ba03a77ac84f52b3912a0edef4cf9" + integrity sha512-x0LvFTekgSX+83TI28Y9wYPUfzrnl2aT5+5QLnO6v7mSJYtEEevuDRN0F0uSHRk1G1IWZC43o00Y0xDDrpBGPQ== + dependencies: + "@babel/helper-string-parser" "^7.27.1" + "@babel/helper-validator-identifier" "^7.27.1" + +"@braintree/sanitize-url@^6.0.0": + version "6.0.2" + resolved "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.2.tgz" + integrity sha512-Tbsj02wXCbqGmzdnXNk0SOF19ChhRU70BsroIi4Pm6Ehp56in6vch94mfbdQ17DozxkL3BAVjbZ4Qc1a0HFRAg== + +"@braintree/sanitize-url@^7.0.4": + version "7.1.1" + resolved "https://registry.yarnpkg.com/@braintree/sanitize-url/-/sanitize-url-7.1.1.tgz#15e19737d946559289b915e5dad3b4c28407735e" + integrity sha512-i1L7noDNxtFyL5DmZafWy1wRVhGehQmzZaz1HiN5e7iylJMSZR7ekOV7NsIqa5qBldlLrsKv4HbgFUVlQrz8Mw== + +"@chevrotain/cst-dts-gen@11.0.3": + version "11.0.3" + resolved "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.0.3.tgz" + integrity sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ== + dependencies: + "@chevrotain/gast" "11.0.3" + "@chevrotain/types" "11.0.3" + lodash-es "4.17.21" + +"@chevrotain/gast@11.0.3": + version "11.0.3" + resolved "https://registry.npmjs.org/@chevrotain/gast/-/gast-11.0.3.tgz" + integrity sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q== + dependencies: + "@chevrotain/types" "11.0.3" + lodash-es "4.17.21" + +"@chevrotain/regexp-to-ast@11.0.3": + version "11.0.3" + resolved "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.0.3.tgz" + integrity sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA== + +"@chevrotain/types@11.0.3": + version "11.0.3" + resolved "https://registry.npmjs.org/@chevrotain/types/-/types-11.0.3.tgz" + integrity sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ== + +"@chevrotain/utils@11.0.3": + version "11.0.3" + resolved "https://registry.npmjs.org/@chevrotain/utils/-/utils-11.0.3.tgz" + integrity sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ== + +"@docsearch/css@3.6.2", "@docsearch/css@^3.6.2": + version "3.6.2" + resolved "https://registry.npmjs.org/@docsearch/css/-/css-3.6.2.tgz" + integrity sha512-vKNZepO2j7MrYBTZIGXvlUOIR+v9KRf70FApRgovWrj3GTs1EITz/Xb0AOlm1xsQBp16clVZj1SY/qaOJbQtZw== + +"@docsearch/js@^3.6.2": + version "3.6.2" + resolved "https://registry.npmjs.org/@docsearch/js/-/js-3.6.2.tgz" + integrity sha512-pS4YZF+VzUogYrkblCucQ0Oy2m8Wggk8Kk7lECmZM60hTbaydSIhJTTiCrmoxtBqV8wxORnOqcqqOfbmkkQEcA== + dependencies: + "@docsearch/react" "3.6.2" + preact "^10.0.0" + +"@docsearch/react@3.6.2": + version "3.6.2" + resolved "https://registry.npmjs.org/@docsearch/react/-/react-3.6.2.tgz" + integrity sha512-rtZce46OOkVflCQH71IdbXSFK+S8iJZlUF56XBW5rIgx/eG5qoomC7Ag3anZson1bBac/JFQn7XOBfved/IMRA== + dependencies: + "@algolia/autocomplete-core" "1.9.3" + "@algolia/autocomplete-preset-algolia" "1.9.3" + "@docsearch/css" "3.6.2" + algoliasearch "^4.19.1" + +"@esbuild/aix-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f" + integrity sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ== + +"@esbuild/android-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz#09d9b4357780da9ea3a7dfb833a1f1ff439b4052" + integrity sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A== + +"@esbuild/android-arm@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz#9b04384fb771926dfa6d7ad04324ecb2ab9b2e28" + integrity sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg== + +"@esbuild/android-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz#29918ec2db754cedcb6c1b04de8cd6547af6461e" + integrity sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA== + +"@esbuild/darwin-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz" + integrity sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ== + +"@esbuild/darwin-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz#c13838fa57372839abdddc91d71542ceea2e1e22" + integrity sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw== + +"@esbuild/freebsd-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz#646b989aa20bf89fd071dd5dbfad69a3542e550e" + integrity sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g== + +"@esbuild/freebsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz#aa615cfc80af954d3458906e38ca22c18cf5c261" + integrity sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ== + +"@esbuild/linux-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz#70ac6fa14f5cb7e1f7f887bcffb680ad09922b5b" + integrity sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q== + +"@esbuild/linux-arm@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz#fc6fd11a8aca56c1f6f3894f2bea0479f8f626b9" + integrity sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA== + +"@esbuild/linux-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz#3271f53b3f93e3d093d518d1649d6d68d346ede2" + integrity sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg== + +"@esbuild/linux-loong64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz#ed62e04238c57026aea831c5a130b73c0f9f26df" + integrity sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg== + +"@esbuild/linux-mips64el@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz#e79b8eb48bf3b106fadec1ac8240fb97b4e64cbe" + integrity sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg== + +"@esbuild/linux-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz#5f2203860a143b9919d383ef7573521fb154c3e4" + integrity sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w== + +"@esbuild/linux-riscv64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz#07bcafd99322d5af62f618cb9e6a9b7f4bb825dc" + integrity sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA== + +"@esbuild/linux-s390x@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz#b7ccf686751d6a3e44b8627ababc8be3ef62d8de" + integrity sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A== + +"@esbuild/linux-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz#6d8f0c768e070e64309af8004bb94e68ab2bb3b0" + integrity sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ== + +"@esbuild/netbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz#bbe430f60d378ecb88decb219c602667387a6047" + integrity sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg== + +"@esbuild/openbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz#99d1cf2937279560d2104821f5ccce220cb2af70" + integrity sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow== + +"@esbuild/sunos-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz#08741512c10d529566baba837b4fe052c8f3487b" + integrity sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg== + +"@esbuild/win32-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz#675b7385398411240735016144ab2e99a60fc75d" + integrity sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A== + +"@esbuild/win32-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz#1bfc3ce98aa6ca9a0969e4d2af72144c59c1193b" + integrity sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA== + +"@esbuild/win32-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz#acad351d582d157bb145535db2a6ff53dd514b5c" + integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw== + +"@floating-ui/core@^1.7.2": + version "1.7.2" + resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.7.2.tgz#3d1c35263950b314b6d5a72c8bfb9e3c1551aefd" + integrity sha512-wNB5ooIKHQc+Kui96jE/n69rHFWAVoxn5CAzL1Xdd8FG03cgY3MLO+GF9U3W737fYDSgPWA6MReKhBQBop6Pcw== + dependencies: + "@floating-ui/utils" "^0.2.10" + +"@floating-ui/dom@^1.6.13", "@floating-ui/dom@^1.7.2": + version "1.7.2" + resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.7.2.tgz#3540b051cf5ce0d4f4db5fb2507a76e8ea5b4a45" + integrity sha512-7cfaOQuCS27HD7DX+6ib2OrnW+b4ZBwDNnCcT0uTyidcmyWb03FnQqJybDBoCnpdxwBSfA94UAYlRCt7mV+TbA== + dependencies: + "@floating-ui/core" "^1.7.2" + "@floating-ui/utils" "^0.2.10" + +"@floating-ui/utils@^0.2.10": + version "0.2.10" + resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.10.tgz#a2a1e3812d14525f725d011a73eceb41fef5bc1c" + integrity sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ== + +"@floating-ui/vue@^1.1.6": + version "1.1.7" + resolved "https://registry.yarnpkg.com/@floating-ui/vue/-/vue-1.1.7.tgz#64d70a7fecd0a671853c2cdb70ff60d0b4773e43" + integrity sha512-idmAtbAIigGXN2SI5gItiXYBYtNfDTP9yIiObxgu13dgtG7ARCHlNfnR29GxP4LI4o13oiwsJ8wVgghj1lNqcw== + dependencies: + "@floating-ui/dom" "^1.7.2" + "@floating-ui/utils" "^0.2.10" + vue-demi ">=0.13.0" + +"@iconify-json/simple-icons@^1.2.10": + version "1.2.11" + resolved "https://registry.npmjs.org/@iconify-json/simple-icons/-/simple-icons-1.2.11.tgz" + integrity sha512-AHCGDtBRqP+JzAbBzgO8uN/08CXxEmuaC6lQQZ3b5burKhRU12AJnJczwbUw2K5Mb/U85EpSUNhYMG3F28b8NA== + dependencies: + "@iconify/types" "*" + +"@iconify/types@*", "@iconify/types@^2.0.0": + version "2.0.0" + resolved "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz" + integrity sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg== + +"@iconify/utils@^2.1.33": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@iconify/utils/-/utils-2.3.0.tgz#1bbbf8c477ebe9a7cacaea78b1b7e8937f9cbfba" + integrity sha512-GmQ78prtwYW6EtzXRU1rY+KwOKfz32PD7iJh6Iyqw68GiKuoZ2A6pRtzWONz5VQJbp50mEjXh/7NkumtrAgRKA== + dependencies: + "@antfu/install-pkg" "^1.0.0" + "@antfu/utils" "^8.1.0" + "@iconify/types" "^2.0.0" + debug "^4.4.0" + globals "^15.14.0" + kolorist "^1.8.0" + local-pkg "^1.0.0" + mlly "^1.7.4" + +"@internationalized/date@^3.5.0": + version "3.8.2" + resolved "https://registry.yarnpkg.com/@internationalized/date/-/date-3.8.2.tgz#977620c1407cc6830fd44cb505679d23c599e119" + integrity sha512-/wENk7CbvLbkUvX1tu0mwq49CVkkWpkXubGel6birjRPyo6uQ4nQpnq5xZu823zRCwwn82zgHrvgF1vZyvmVgA== + dependencies: + "@swc/helpers" "^0.5.0" + +"@internationalized/number@^3.5.0": + version "3.6.4" + resolved "https://registry.yarnpkg.com/@internationalized/number/-/number-3.6.4.tgz#3ab593fec5e87654fdece0a3238cdc9d0eedff8a" + integrity sha512-P+/h+RDaiX8EGt3shB9AYM1+QgkvHmJ5rKi4/59k4sg9g58k9rqsRW0WxRO7jCoHyvVbFRRFKmVTdFYdehrxHg== + dependencies: + "@swc/helpers" "^0.5.0" + +"@jridgewell/gen-mapping@^0.3.5": + version "0.3.12" + resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz" + integrity sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg== + dependencies: + "@jridgewell/sourcemap-codec" "^1.5.0" + "@jridgewell/trace-mapping" "^0.3.24" + +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.2" + resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== + +"@jridgewell/source-map@^0.3.3": + version "0.3.10" + resolved "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.10.tgz" + integrity sha512-0pPkgz9dY+bijgistcTTJ5mR+ocqRXLuhXHYdzoMmmoJ2C9S46RCm2GMUbatPEUK9Yjy26IrAy8D/M00lLkv+Q== + dependencies: + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" + +"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0": + version "1.5.0" + resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz" + integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== + +"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": + version "0.3.29" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz" + integrity sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@mermaid-js/mermaid-mindmap@^9.3.0": + version "9.3.0" + resolved "https://registry.npmjs.org/@mermaid-js/mermaid-mindmap/-/mermaid-mindmap-9.3.0.tgz" + integrity sha512-IhtYSVBBRYviH1Ehu8gk69pMDF8DSRqXBRDMWrEfHoaMruHeaP2DXA3PBnuwsMaCdPQhlUUcy/7DBLAEIXvCAw== + dependencies: + "@braintree/sanitize-url" "^6.0.0" + cytoscape "^3.23.0" + cytoscape-cose-bilkent "^4.1.0" + cytoscape-fcose "^2.1.0" + d3 "^7.0.0" + khroma "^2.0.0" + non-layered-tidy-tree-layout "^2.0.2" + +"@mermaid-js/parser@^0.6.2": + version "0.6.2" + resolved "https://registry.npmjs.org/@mermaid-js/parser/-/parser-0.6.2.tgz" + integrity sha512-+PO02uGF6L6Cs0Bw8RpGhikVvMWEysfAyl27qTlroUB8jSWr1lL0Sf6zi78ZxlSnmgSY2AMMKVgghnN9jTtwkQ== + dependencies: + langium "3.3.1" + +"@rollup/rollup-android-arm-eabi@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz#8b613b9725e8f9479d142970b106b6ae878610d5" + integrity sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w== + +"@rollup/rollup-android-arm64@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.4.tgz#654ca1049189132ff602bfcf8df14c18da1f15fb" + integrity sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA== + +"@rollup/rollup-darwin-arm64@4.22.4": + version "4.22.4" + resolved "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.4.tgz" + integrity sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q== + +"@rollup/rollup-darwin-x64@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.4.tgz#42bd19d292a57ee11734c980c4650de26b457791" + integrity sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw== + +"@rollup/rollup-linux-arm-gnueabihf@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.4.tgz#f23555ee3d8fe941c5c5fd458cd22b65eb1c2232" + integrity sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ== + +"@rollup/rollup-linux-arm-musleabihf@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.4.tgz#f3bbd1ae2420f5539d40ac1fde2b38da67779baa" + integrity sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg== + +"@rollup/rollup-linux-arm64-gnu@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.4.tgz#7abe900120113e08a1f90afb84c7c28774054d15" + integrity sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw== + +"@rollup/rollup-linux-arm64-musl@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.4.tgz#9e655285c8175cd44f57d6a1e8e5dedfbba1d820" + integrity sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA== + +"@rollup/rollup-linux-powerpc64le-gnu@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.4.tgz#9a79ae6c9e9d8fe83d49e2712ecf4302db5bef5e" + integrity sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg== + +"@rollup/rollup-linux-riscv64-gnu@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.4.tgz#67ac70eca4ace8e2942fabca95164e8874ab8128" + integrity sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA== + +"@rollup/rollup-linux-s390x-gnu@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.4.tgz#9f883a7440f51a22ed7f99e1d070bd84ea5005fc" + integrity sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q== + +"@rollup/rollup-linux-x64-gnu@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.4.tgz#70116ae6c577fe367f58559e2cffb5641a1dd9d0" + integrity sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg== + +"@rollup/rollup-linux-x64-musl@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.4.tgz#f473f88219feb07b0b98b53a7923be716d1d182f" + integrity sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g== + +"@rollup/rollup-win32-arm64-msvc@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.4.tgz#4349482d17f5d1c58604d1c8900540d676f420e0" + integrity sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw== + +"@rollup/rollup-win32-ia32-msvc@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.4.tgz#a6fc39a15db618040ec3c2a24c1e26cb5f4d7422" + integrity sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g== + +"@rollup/rollup-win32-x64-msvc@4.22.4": + version "4.22.4" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.4.tgz#3dd5d53e900df2a40841882c02e56f866c04d202" + integrity sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q== + +"@shikijs/core@1.22.2", "@shikijs/core@^1.22.2": + version "1.22.2" + resolved "https://registry.npmjs.org/@shikijs/core/-/core-1.22.2.tgz" + integrity sha512-bvIQcd8BEeR1yFvOYv6HDiyta2FFVePbzeowf5pPS1avczrPK+cjmaxxh0nx5QzbON7+Sv0sQfQVciO7bN72sg== + dependencies: + "@shikijs/engine-javascript" "1.22.2" + "@shikijs/engine-oniguruma" "1.22.2" + "@shikijs/types" "1.22.2" + "@shikijs/vscode-textmate" "^9.3.0" + "@types/hast" "^3.0.4" + hast-util-to-html "^9.0.3" + +"@shikijs/engine-javascript@1.22.2": + version "1.22.2" + resolved "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-1.22.2.tgz" + integrity sha512-iOvql09ql6m+3d1vtvP8fLCVCK7BQD1pJFmHIECsujB0V32BJ0Ab6hxk1ewVSMFA58FI0pR2Had9BKZdyQrxTw== + dependencies: + "@shikijs/types" "1.22.2" + "@shikijs/vscode-textmate" "^9.3.0" + oniguruma-to-js "0.4.3" + +"@shikijs/engine-oniguruma@1.22.2": + version "1.22.2" + resolved "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-1.22.2.tgz" + integrity sha512-GIZPAGzQOy56mGvWMoZRPggn0dTlBf1gutV5TdceLCZlFNqWmuc7u+CzD0Gd9vQUTgLbrt0KLzz6FNprqYAxlA== + dependencies: + "@shikijs/types" "1.22.2" + "@shikijs/vscode-textmate" "^9.3.0" + +"@shikijs/transformers@^1.22.2": + version "1.22.2" + resolved "https://registry.npmjs.org/@shikijs/transformers/-/transformers-1.22.2.tgz" + integrity sha512-8f78OiBa6pZDoZ53lYTmuvpFPlWtevn23bzG+azpPVvZg7ITax57o/K3TC91eYL3OMJOO0onPbgnQyZjRos8XQ== + dependencies: + shiki "1.22.2" + +"@shikijs/types@1.22.2", "@shikijs/types@^1.22.2": + version "1.22.2" + resolved "https://registry.npmjs.org/@shikijs/types/-/types-1.22.2.tgz" + integrity sha512-NCWDa6LGZqTuzjsGfXOBWfjS/fDIbDdmVDug+7ykVe1IKT4c1gakrvlfFYp5NhAXH/lyqLM8wsAPo5wNy73Feg== + dependencies: + "@shikijs/vscode-textmate" "^9.3.0" + "@types/hast" "^3.0.4" + +"@shikijs/vscode-textmate@^9.3.0": + version "9.3.0" + resolved "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-9.3.0.tgz" + integrity sha512-jn7/7ky30idSkd/O5yDBfAnVt+JJpepofP/POZ1iMOxK59cOfqIgg/Dj0eFsjOTMw+4ycJN0uhZH/Eb0bs/EUA== + +"@swc/helpers@^0.5.0": + version "0.5.17" + resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.17.tgz#5a7be95ac0f0bf186e7e6e890e7a6f6cda6ce971" + integrity sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A== + dependencies: + tslib "^2.8.0" + +"@tanstack/virtual-core@3.13.12": + version "3.13.12" + resolved "https://registry.yarnpkg.com/@tanstack/virtual-core/-/virtual-core-3.13.12.tgz#1dff176df9cc8f93c78c5e46bcea11079b397578" + integrity sha512-1YBOJfRHV4sXUmWsFSf5rQor4Ss82G8dQWLRbnk3GA4jeP8hQt1hxXh0tmflpC0dz3VgEv/1+qwPyLeWkQuPFA== + +"@tanstack/vue-virtual@^3.12.0": + version "3.13.12" + resolved "https://registry.yarnpkg.com/@tanstack/vue-virtual/-/vue-virtual-3.13.12.tgz#a66daac9e6822ce4bcba76a3954937440697c264" + integrity sha512-vhF7kEU9EXWXh+HdAwKJ2m3xaOnTTmgcdXcF2pim8g4GvI7eRrk2YRuV5nUlZnd/NbCIX4/Ja2OZu5EjJL06Ww== + dependencies: + "@tanstack/virtual-core" "3.13.12" + +"@types/d3-array@*": + version "3.2.1" + resolved "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz" + integrity sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg== + +"@types/d3-axis@*": + version "3.0.6" + resolved "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz" + integrity sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw== + dependencies: + "@types/d3-selection" "*" + +"@types/d3-brush@*": + version "3.0.6" + resolved "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz" + integrity sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A== + dependencies: + "@types/d3-selection" "*" + +"@types/d3-chord@*": + version "3.0.6" + resolved "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz" + integrity sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg== + +"@types/d3-color@*": + version "3.1.3" + resolved "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz" + integrity sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A== + +"@types/d3-contour@*": + version "3.0.6" + resolved "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz" + integrity sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg== + dependencies: + "@types/d3-array" "*" + "@types/geojson" "*" + +"@types/d3-delaunay@*": + version "6.0.4" + resolved "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz" + integrity sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw== + +"@types/d3-dispatch@*": + version "3.0.6" + resolved "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.6.tgz" + integrity sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ== + +"@types/d3-drag@*": + version "3.0.7" + resolved "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz" + integrity sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ== + dependencies: + "@types/d3-selection" "*" + +"@types/d3-dsv@*": + version "3.0.7" + resolved "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz" + integrity sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g== + +"@types/d3-ease@*": + version "3.0.2" + resolved "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz" + integrity sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA== + +"@types/d3-fetch@*": + version "3.0.7" + resolved "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz" + integrity sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA== + dependencies: + "@types/d3-dsv" "*" + +"@types/d3-force@*": + version "3.0.10" + resolved "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz" + integrity sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw== + +"@types/d3-format@*": + version "3.0.4" + resolved "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz" + integrity sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g== + +"@types/d3-geo@*": + version "3.1.0" + resolved "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz" + integrity sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ== + dependencies: + "@types/geojson" "*" + +"@types/d3-hierarchy@*": + version "3.1.7" + resolved "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz" + integrity sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg== + +"@types/d3-interpolate@*": + version "3.0.4" + resolved "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz" + integrity sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA== + dependencies: + "@types/d3-color" "*" + +"@types/d3-path@*": + version "3.1.1" + resolved "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz" + integrity sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg== + +"@types/d3-polygon@*": + version "3.0.2" + resolved "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz" + integrity sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA== + +"@types/d3-quadtree@*": + version "3.0.6" + resolved "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz" + integrity sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg== + +"@types/d3-random@*": + version "3.0.3" + resolved "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz" + integrity sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ== + +"@types/d3-scale-chromatic@*": + version "3.1.0" + resolved "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz" + integrity sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ== + +"@types/d3-scale@*": + version "4.0.9" + resolved "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz" + integrity sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw== + dependencies: + "@types/d3-time" "*" + +"@types/d3-selection@*": + version "3.0.11" + resolved "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz" + integrity sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w== + +"@types/d3-shape@*": + version "3.1.7" + resolved "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz" + integrity sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg== + dependencies: + "@types/d3-path" "*" + +"@types/d3-time-format@*": + version "4.0.3" + resolved "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz" + integrity sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg== + +"@types/d3-time@*": + version "3.0.4" + resolved "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz" + integrity sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g== + +"@types/d3-timer@*": + version "3.0.2" + resolved "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz" + integrity sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw== + +"@types/d3-transition@*": + version "3.0.9" + resolved "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz" + integrity sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg== + dependencies: + "@types/d3-selection" "*" + +"@types/d3-zoom@*": + version "3.0.8" + resolved "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz" + integrity sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw== + dependencies: + "@types/d3-interpolate" "*" + "@types/d3-selection" "*" + +"@types/d3@^7.4.3": + version "7.4.3" + resolved "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz" + integrity sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww== + dependencies: + "@types/d3-array" "*" + "@types/d3-axis" "*" + "@types/d3-brush" "*" + "@types/d3-chord" "*" + "@types/d3-color" "*" + "@types/d3-contour" "*" + "@types/d3-delaunay" "*" + "@types/d3-dispatch" "*" + "@types/d3-drag" "*" + "@types/d3-dsv" "*" + "@types/d3-ease" "*" + "@types/d3-fetch" "*" + "@types/d3-force" "*" + "@types/d3-format" "*" + "@types/d3-geo" "*" + "@types/d3-hierarchy" "*" + "@types/d3-interpolate" "*" + "@types/d3-path" "*" + "@types/d3-polygon" "*" + "@types/d3-quadtree" "*" + "@types/d3-random" "*" + "@types/d3-scale" "*" + "@types/d3-scale-chromatic" "*" + "@types/d3-selection" "*" + "@types/d3-shape" "*" + "@types/d3-time" "*" + "@types/d3-time-format" "*" + "@types/d3-timer" "*" + "@types/d3-transition" "*" + "@types/d3-zoom" "*" + +"@types/estree@1.0.5": + version "1.0.5" + resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz" + integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== + +"@types/geojson@*": + version "7946.0.16" + resolved "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz" + integrity sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg== + +"@types/hast@^3.0.0", "@types/hast@^3.0.4": + version "3.0.4" + resolved "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz" + integrity sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ== + dependencies: + "@types/unist" "*" + +"@types/linkify-it@^5": + version "5.0.0" + resolved "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz" + integrity sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q== + +"@types/markdown-it@^14.1.2": + version "14.1.2" + resolved "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz" + integrity sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog== + dependencies: + "@types/linkify-it" "^5" + "@types/mdurl" "^2" + +"@types/mdast@^4.0.0": + version "4.0.4" + resolved "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz" + integrity sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA== + dependencies: + "@types/unist" "*" + +"@types/mdurl@^2": + version "2.0.0" + resolved "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz" + integrity sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg== + +"@types/trusted-types@^2.0.7": + version "2.0.7" + resolved "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz" + integrity sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw== + +"@types/unist@*", "@types/unist@^3.0.0": + version "3.0.3" + resolved "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz" + integrity sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q== + +"@types/web-bluetooth@^0.0.20": + version "0.0.20" + resolved "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz" + integrity sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow== + +"@types/web-bluetooth@^0.0.21": + version "0.0.21" + resolved "https://registry.yarnpkg.com/@types/web-bluetooth/-/web-bluetooth-0.0.21.tgz#525433c784aed9b457aaa0ee3d92aeb71f346b63" + integrity sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA== + +"@ungap/structured-clone@^1.0.0": + version "1.2.0" + resolved "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz" + integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== + +"@vitejs/plugin-vue@^5.1.4": + version "5.1.4" + resolved "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.1.4.tgz" + integrity sha512-N2XSI2n3sQqp5w7Y/AN/L2XDjBIRGqXko+eDp42sydYSBeJuSm5a1sLf8zakmo8u7tA8NmBgoDLA1HeOESjp9A== + +"@vue/compiler-core@3.5.12": + version "3.5.12" + resolved "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.12.tgz" + integrity sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw== + dependencies: + "@babel/parser" "^7.25.3" + "@vue/shared" "3.5.12" + entities "^4.5.0" + estree-walker "^2.0.2" + source-map-js "^1.2.0" + +"@vue/compiler-core@3.5.18": + version "3.5.18" + resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.5.18.tgz#521a138cdd970d9bfd27e42168d12f77a04b2074" + integrity sha512-3slwjQrrV1TO8MoXgy3aynDQ7lslj5UqDxuHnrzHtpON5CBinhWjJETciPngpin/T3OuW3tXUf86tEurusnztw== + dependencies: + "@babel/parser" "^7.28.0" + "@vue/shared" "3.5.18" + entities "^4.5.0" + estree-walker "^2.0.2" + source-map-js "^1.2.1" + +"@vue/compiler-dom@3.5.12": + version "3.5.12" + resolved "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.12.tgz" + integrity sha512-9G6PbJ03uwxLHKQ3P42cMTi85lDRvGLB2rSGOiQqtXELat6uI4n8cNz9yjfVHRPIu+MsK6TE418Giruvgptckg== + dependencies: + "@vue/compiler-core" "3.5.12" + "@vue/shared" "3.5.12" + +"@vue/compiler-dom@3.5.18": + version "3.5.18" + resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.5.18.tgz#e13504492c3061ec5bbe6a2e789f15261d4f03a7" + integrity sha512-RMbU6NTU70++B1JyVJbNbeFkK+A+Q7y9XKE2EM4NLGm2WFR8x9MbAtWxPPLdm0wUkuZv9trpwfSlL6tjdIa1+A== + dependencies: + "@vue/compiler-core" "3.5.18" + "@vue/shared" "3.5.18" + +"@vue/compiler-sfc@3.5.12": + version "3.5.12" + resolved "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.12.tgz" + integrity sha512-2k973OGo2JuAa5+ZlekuQJtitI5CgLMOwgl94BzMCsKZCX/xiqzJYzapl4opFogKHqwJk34vfsaKpfEhd1k5nw== + dependencies: + "@babel/parser" "^7.25.3" + "@vue/compiler-core" "3.5.12" + "@vue/compiler-dom" "3.5.12" + "@vue/compiler-ssr" "3.5.12" + "@vue/shared" "3.5.12" + estree-walker "^2.0.2" + magic-string "^0.30.11" + postcss "^8.4.47" + source-map-js "^1.2.0" + +"@vue/compiler-sfc@3.5.18": + version "3.5.18" + resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.5.18.tgz#ba1e849561337d809937994cdaf900539542eeca" + integrity sha512-5aBjvGqsWs+MoxswZPoTB9nSDb3dhd1x30xrrltKujlCxo48j8HGDNj3QPhF4VIS0VQDUrA1xUfp2hEa+FNyXA== + dependencies: + "@babel/parser" "^7.28.0" + "@vue/compiler-core" "3.5.18" + "@vue/compiler-dom" "3.5.18" + "@vue/compiler-ssr" "3.5.18" + "@vue/shared" "3.5.18" + estree-walker "^2.0.2" + magic-string "^0.30.17" + postcss "^8.5.6" + source-map-js "^1.2.1" + +"@vue/compiler-ssr@3.5.12": + version "3.5.12" + resolved "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.12.tgz" + integrity sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA== + dependencies: + "@vue/compiler-dom" "3.5.12" + "@vue/shared" "3.5.12" + +"@vue/compiler-ssr@3.5.18": + version "3.5.18" + resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.5.18.tgz#aecde0b0bff268a9c9014ba66799307c4a784328" + integrity sha512-xM16Ak7rSWHkM3m22NlmcdIM+K4BMyFARAfV9hYFl+SFuRzrZ3uGMNW05kA5pmeMa0X9X963Kgou7ufdbpOP9g== + dependencies: + "@vue/compiler-dom" "3.5.18" + "@vue/shared" "3.5.18" + +"@vue/devtools-api@^7.5.4": + version "7.6.2" + resolved "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.6.2.tgz" + integrity sha512-NCT0ujqlwAhoFvCsAG7G5qS8w/A/dhvFSt2BhmNxyqgpYDrf9CG1zYyWLQkE3dsZ+5lCT6ULUic2VKNaE07Vzg== + dependencies: + "@vue/devtools-kit" "^7.6.2" + +"@vue/devtools-kit@^7.6.2": + version "7.6.2" + resolved "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.6.2.tgz" + integrity sha512-k61BxHRmcTtIQZFouF9QWt9nCCNtSdw12lhg8VNtHq5/XOBGD+ewiK27a40UJ8UPYoCJvi80hbvbYr5E/Zeu1g== + dependencies: + "@vue/devtools-shared" "^7.6.2" + birpc "^0.2.19" + hookable "^5.5.3" + mitt "^3.0.1" + perfect-debounce "^1.0.0" + speakingurl "^14.0.1" + superjson "^2.2.1" + +"@vue/devtools-shared@^7.6.2": + version "7.6.2" + resolved "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.6.2.tgz" + integrity sha512-lcjyJ7hCC0W0kNwnCGMLVTMvDLoZgjcq9BvboPgS+6jQyDul7fpzRSKTGtGhCHoxrDox7qBAKGbAl2Rcf7GE1A== + dependencies: + rfdc "^1.4.1" + +"@vue/reactivity@3.5.12": + version "3.5.12" + resolved "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.12.tgz" + integrity sha512-UzaN3Da7xnJXdz4Okb/BGbAaomRHc3RdoWqTzlvd9+WBR5m3J39J1fGcHes7U3za0ruYn/iYy/a1euhMEHvTAg== + dependencies: + "@vue/shared" "3.5.12" + +"@vue/reactivity@3.5.18": + version "3.5.18" + resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.5.18.tgz#fe32166e3938832c54b4134e60e9b58ca7d9bdb4" + integrity sha512-x0vPO5Imw+3sChLM5Y+B6G1zPjwdOri9e8V21NnTnlEvkxatHEH5B5KEAJcjuzQ7BsjGrKtfzuQ5eQwXh8HXBg== + dependencies: + "@vue/shared" "3.5.18" + +"@vue/runtime-core@3.5.12": + version "3.5.12" + resolved "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.12.tgz" + integrity sha512-hrMUYV6tpocr3TL3Ad8DqxOdpDe4zuQY4HPY3X/VRh+L2myQO8MFXPAMarIOSGNu0bFAjh1yBkMPXZBqCk62Uw== + dependencies: + "@vue/reactivity" "3.5.12" + "@vue/shared" "3.5.12" + +"@vue/runtime-core@3.5.18": + version "3.5.18" + resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.5.18.tgz#9e9ae8b9491548b53d0cea2bf25746d27c52e191" + integrity sha512-DUpHa1HpeOQEt6+3nheUfqVXRog2kivkXHUhoqJiKR33SO4x+a5uNOMkV487WPerQkL0vUuRvq/7JhRgLW3S+w== + dependencies: + "@vue/reactivity" "3.5.18" + "@vue/shared" "3.5.18" + +"@vue/runtime-dom@3.5.12": + version "3.5.12" + resolved "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.12.tgz" + integrity sha512-q8VFxR9A2MRfBr6/55Q3umyoN7ya836FzRXajPB6/Vvuv0zOPL+qltd9rIMzG/DbRLAIlREmnLsplEF/kotXKA== + dependencies: + "@vue/reactivity" "3.5.12" + "@vue/runtime-core" "3.5.12" + "@vue/shared" "3.5.12" + csstype "^3.1.3" + +"@vue/runtime-dom@3.5.18": + version "3.5.18" + resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.5.18.tgz#1150952d1048b5822e4f1dd8aed24665cbb22107" + integrity sha512-YwDj71iV05j4RnzZnZtGaXwPoUWeRsqinblgVJwR8XTXYZ9D5PbahHQgsbmzUvCWNF6x7siQ89HgnX5eWkr3mw== + dependencies: + "@vue/reactivity" "3.5.18" + "@vue/runtime-core" "3.5.18" + "@vue/shared" "3.5.18" + csstype "^3.1.3" + +"@vue/server-renderer@3.5.12": + version "3.5.12" + resolved "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.12.tgz" + integrity sha512-I3QoeDDeEPZm8yR28JtY+rk880Oqmj43hreIBVTicisFTx/Dl7JpG72g/X7YF8hnQD3IFhkky5i2bPonwrTVPg== + dependencies: + "@vue/compiler-ssr" "3.5.12" + "@vue/shared" "3.5.12" + +"@vue/server-renderer@3.5.18": + version "3.5.18" + resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.5.18.tgz#e9fa267b95b3a1d8cddca762377e5de2ae9122bd" + integrity sha512-PvIHLUoWgSbDG7zLHqSqaCoZvHi6NNmfVFOqO+OnwvqMz/tqQr3FuGWS8ufluNddk7ZLBJYMrjcw1c6XzR12mA== + dependencies: + "@vue/compiler-ssr" "3.5.18" + "@vue/shared" "3.5.18" + +"@vue/shared@3.5.12", "@vue/shared@^3.5.12": + version "3.5.12" + resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.5.12.tgz" + integrity sha512-L2RPSAwUFbgZH20etwrXyVyCBu9OxRSi8T/38QsvnkJyvq2LufW2lDCOzm7t/U9C1mkhJGWYfCuFBCmIuNivrg== + +"@vue/shared@3.5.18": + version "3.5.18" + resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.5.18.tgz#529f24a88d3ed678d50fd5c07455841fbe8ac95e" + integrity sha512-cZy8Dq+uuIXbxCZpuLd2GJdeSO/lIzIspC2WtkqIpje5QyFbvLaI5wZtdUjLHjGZrlVX6GilejatWwVYYRc8tA== + +"@vueuse/core@11.1.0", "@vueuse/core@^11.1.0": + version "11.1.0" + resolved "https://registry.npmjs.org/@vueuse/core/-/core-11.1.0.tgz" + integrity sha512-P6dk79QYA6sKQnghrUz/1tHi0n9mrb/iO1WTMk/ElLmTyNqgDeSZ3wcDf6fRBGzRJbeG1dxzEOvLENMjr+E3fg== + dependencies: + "@types/web-bluetooth" "^0.0.20" + "@vueuse/metadata" "11.1.0" + "@vueuse/shared" "11.1.0" + vue-demi ">=0.14.10" + +"@vueuse/core@^12.5.0": + version "12.8.2" + resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-12.8.2.tgz#007c6dd29a7d1f6933e916e7a2f8ef3c3f968eaa" + integrity sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ== + dependencies: + "@types/web-bluetooth" "^0.0.21" + "@vueuse/metadata" "12.8.2" + "@vueuse/shared" "12.8.2" + vue "^3.5.13" + +"@vueuse/core@^13.1.0": + version "13.5.0" + resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-13.5.0.tgz#1136d3db088945d7b7a2397170737d5a3e557b36" + integrity sha512-wV7z0eUpifKmvmN78UBZX8T7lMW53Nrk6JP5+6hbzrB9+cJ3jr//hUlhl9TZO/03bUkMK6gGkQpqOPWoabr72g== + dependencies: + "@types/web-bluetooth" "^0.0.21" + "@vueuse/metadata" "13.5.0" + "@vueuse/shared" "13.5.0" + +"@vueuse/integrations@^11.1.0": + version "11.1.0" + resolved "https://registry.npmjs.org/@vueuse/integrations/-/integrations-11.1.0.tgz" + integrity sha512-O2ZgrAGPy0qAjpoI2YR3egNgyEqwG85fxfwmA9BshRIGjV4G6yu6CfOPpMHAOoCD+UfsIl7Vb1bXJ6ifrHYDDA== + dependencies: + "@vueuse/core" "11.1.0" + "@vueuse/shared" "11.1.0" + vue-demi ">=0.14.10" + +"@vueuse/metadata@11.1.0": + version "11.1.0" + resolved "https://registry.npmjs.org/@vueuse/metadata/-/metadata-11.1.0.tgz" + integrity sha512-l9Q502TBTaPYGanl1G+hPgd3QX5s4CGnpXriVBR5fEZ/goI6fvDaVmIl3Td8oKFurOxTmbXvBPSsgrd6eu6HYg== + +"@vueuse/metadata@12.8.2": + version "12.8.2" + resolved "https://registry.yarnpkg.com/@vueuse/metadata/-/metadata-12.8.2.tgz#6cb3a4e97cdcf528329eebc1bda73cd7f64318d3" + integrity sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A== + +"@vueuse/metadata@13.5.0": + version "13.5.0" + resolved "https://registry.yarnpkg.com/@vueuse/metadata/-/metadata-13.5.0.tgz#18c24a32489b0a4fb9d7436efc048e836bfc4799" + integrity sha512-euhItU3b0SqXxSy8u1XHxUCdQ8M++bsRs+TYhOLDU/OykS7KvJnyIFfep0XM5WjIFry9uAPlVSjmVHiqeshmkw== + +"@vueuse/shared@11.1.0": + version "11.1.0" + resolved "https://registry.npmjs.org/@vueuse/shared/-/shared-11.1.0.tgz" + integrity sha512-YUtIpY122q7osj+zsNMFAfMTubGz0sn5QzE5gPzAIiCmtt2ha3uQUY1+JPyL4gRCTsLPX82Y9brNbo/aqlA91w== + dependencies: + vue-demi ">=0.14.10" + +"@vueuse/shared@12.8.2", "@vueuse/shared@^12.5.0": + version "12.8.2" + resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-12.8.2.tgz#b9e4611d0603629c8e151f982459da394e22f930" + integrity sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w== + dependencies: + vue "^3.5.13" + +"@vueuse/shared@13.5.0": + version "13.5.0" + resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-13.5.0.tgz#c36e3e0eafca9c3b92356ccef139db0df7d9905e" + integrity sha512-K7GrQIxJ/ANtucxIXbQlUHdB0TPA8c+q5i+zbrjxuhJCnJ9GtBg75sBSnvmLSxHKPg2Yo8w62PWksl9kwH0Q8g== + +acorn@^8.14.0: + version "8.15.0" + resolved "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz" + integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== + +algoliasearch@^4.19.1: + version "4.24.0" + resolved "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.24.0.tgz" + integrity sha512-bf0QV/9jVejssFBmz2HQLxUadxk574t4iwjCKp5E7NBzwKkrDEhKPISIIjAU/p6K5qDx3qoeh4+26zWN1jmw3g== + dependencies: + "@algolia/cache-browser-local-storage" "4.24.0" + "@algolia/cache-common" "4.24.0" + "@algolia/cache-in-memory" "4.24.0" + "@algolia/client-account" "4.24.0" + "@algolia/client-analytics" "4.24.0" + "@algolia/client-common" "4.24.0" + "@algolia/client-personalization" "4.24.0" + "@algolia/client-search" "4.24.0" + "@algolia/logger-common" "4.24.0" + "@algolia/logger-console" "4.24.0" + "@algolia/recommend" "4.24.0" + "@algolia/requester-browser-xhr" "4.24.0" + "@algolia/requester-common" "4.24.0" + "@algolia/requester-node-http" "4.24.0" + "@algolia/transporter" "4.24.0" + +aria-hidden@^1.2.4: + version "1.2.6" + resolved "https://registry.yarnpkg.com/aria-hidden/-/aria-hidden-1.2.6.tgz#73051c9b088114c795b1ea414e9c0fff874ffc1a" + integrity sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA== + dependencies: + tslib "^2.0.0" + +birpc@^0.2.19: + version "0.2.19" + resolved "https://registry.npmjs.org/birpc/-/birpc-0.2.19.tgz" + integrity sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ== + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +ccount@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz" + integrity sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg== + +character-entities-html4@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz" + integrity sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA== + +character-entities-legacy@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz" + integrity sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ== + +chevrotain-allstar@~0.3.0: + version "0.3.1" + resolved "https://registry.npmjs.org/chevrotain-allstar/-/chevrotain-allstar-0.3.1.tgz" + integrity sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw== + dependencies: + lodash-es "^4.17.21" + +chevrotain@~11.0.3: + version "11.0.3" + resolved "https://registry.npmjs.org/chevrotain/-/chevrotain-11.0.3.tgz" + integrity sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw== + dependencies: + "@chevrotain/cst-dts-gen" "11.0.3" + "@chevrotain/gast" "11.0.3" + "@chevrotain/regexp-to-ast" "11.0.3" + "@chevrotain/types" "11.0.3" + "@chevrotain/utils" "11.0.3" + lodash-es "4.17.21" + +class-variance-authority@^0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/class-variance-authority/-/class-variance-authority-0.7.1.tgz#4008a798a0e4553a781a57ac5177c9fb5d043787" + integrity sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg== + dependencies: + clsx "^2.1.1" + +clsx@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999" + integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA== + +comma-separated-tokens@^2.0.0: + version "2.0.3" + resolved "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz" + integrity sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg== + +commander@7: + version "7.2.0" + resolved "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^8.3.0: + version "8.3.0" + resolved "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz" + integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== + +confbox@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/confbox/-/confbox-0.1.8.tgz#820d73d3b3c82d9bd910652c5d4d599ef8ff8b06" + integrity sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w== + +confbox@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/confbox/-/confbox-0.2.2.tgz#8652f53961c74d9e081784beed78555974a9c110" + integrity sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ== + +copy-anything@^3.0.2: + version "3.0.5" + resolved "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz" + integrity sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w== + dependencies: + is-what "^4.1.8" + +cose-base@^1.0.0: + version "1.0.3" + resolved "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz" + integrity sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg== + dependencies: + layout-base "^1.0.0" + +cose-base@^2.2.0: + version "2.2.0" + resolved "https://registry.npmjs.org/cose-base/-/cose-base-2.2.0.tgz" + integrity sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g== + dependencies: + layout-base "^2.0.0" + +csstype@^3.1.3: + version "3.1.3" + resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz" + integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== + +cytoscape-cose-bilkent@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz" + integrity sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ== + dependencies: + cose-base "^1.0.0" + +cytoscape-fcose@^2.1.0, cytoscape-fcose@^2.2.0: + version "2.2.0" + resolved "https://registry.npmjs.org/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz" + integrity sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ== + dependencies: + cose-base "^2.2.0" + +cytoscape@^3.23.0, cytoscape@^3.29.3: + version "3.33.0" + resolved "https://registry.yarnpkg.com/cytoscape/-/cytoscape-3.33.0.tgz#c08136096f568d0f9b438406ec722f1a093b4e16" + integrity sha512-2d2EwwhaxLWC8ahkH1PpQwCyu6EY3xDRdcEJXrLTb4fOUtVc+YWQalHU67rFS1a6ngj1fgv9dQLtJxP/KAFZEw== + +"d3-array@1 - 2": + version "2.12.1" + resolved "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz" + integrity sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ== + dependencies: + internmap "^1.0.0" + +"d3-array@2 - 3", "d3-array@2.10.0 - 3", "d3-array@2.5.0 - 3", d3-array@3, d3-array@^3.2.0: + version "3.2.4" + resolved "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz" + integrity sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg== + dependencies: + internmap "1 - 2" + +d3-axis@3: + version "3.0.0" + resolved "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz" + integrity sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw== + +d3-brush@3: + version "3.0.0" + resolved "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz" + integrity sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ== + dependencies: + d3-dispatch "1 - 3" + d3-drag "2 - 3" + d3-interpolate "1 - 3" + d3-selection "3" + d3-transition "3" + +d3-chord@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz" + integrity sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g== + dependencies: + d3-path "1 - 3" + +"d3-color@1 - 3", d3-color@3: + version "3.1.0" + resolved "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz" + integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA== + +d3-contour@4: + version "4.0.2" + resolved "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz" + integrity sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA== + dependencies: + d3-array "^3.2.0" + +d3-delaunay@6: + version "6.0.4" + resolved "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz" + integrity sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A== + dependencies: + delaunator "5" + +"d3-dispatch@1 - 3", d3-dispatch@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz" + integrity sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg== + +"d3-drag@2 - 3", d3-drag@3: + version "3.0.0" + resolved "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz" + integrity sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg== + dependencies: + d3-dispatch "1 - 3" + d3-selection "3" + +"d3-dsv@1 - 3", d3-dsv@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz" + integrity sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q== + dependencies: + commander "7" + iconv-lite "0.6" + rw "1" + +"d3-ease@1 - 3", d3-ease@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz" + integrity sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w== + +d3-fetch@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz" + integrity sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw== + dependencies: + d3-dsv "1 - 3" + +d3-force@3: + version "3.0.0" + resolved "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz" + integrity sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg== + dependencies: + d3-dispatch "1 - 3" + d3-quadtree "1 - 3" + d3-timer "1 - 3" + +"d3-format@1 - 3", d3-format@3: + version "3.1.0" + resolved "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz" + integrity sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA== + +d3-geo@3: + version "3.1.0" + resolved "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.0.tgz" + integrity sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA== + dependencies: + d3-array "2.5.0 - 3" + +d3-hierarchy@3: + version "3.1.2" + resolved "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz" + integrity sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA== + +"d3-interpolate@1 - 3", "d3-interpolate@1.2.0 - 3", d3-interpolate@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz" + integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g== + dependencies: + d3-color "1 - 3" + +d3-path@1: + version "1.0.9" + resolved "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz" + integrity sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg== + +"d3-path@1 - 3", d3-path@3, d3-path@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz" + integrity sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ== + +d3-polygon@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz" + integrity sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg== + +"d3-quadtree@1 - 3", d3-quadtree@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz" + integrity sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw== + +d3-random@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz" + integrity sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ== + +d3-sankey@^0.12.3: + version "0.12.3" + resolved "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz" + integrity sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ== + dependencies: + d3-array "1 - 2" + d3-shape "^1.2.0" + +d3-scale-chromatic@3: + version "3.0.0" + resolved "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz" + integrity sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g== + dependencies: + d3-color "1 - 3" + d3-interpolate "1 - 3" + +d3-scale@4: + version "4.0.2" + resolved "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz" + integrity sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ== + dependencies: + d3-array "2.10.0 - 3" + d3-format "1 - 3" + d3-interpolate "1.2.0 - 3" + d3-time "2.1.1 - 3" + d3-time-format "2 - 4" + +"d3-selection@2 - 3", d3-selection@3: + version "3.0.0" + resolved "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz" + integrity sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ== + +d3-shape@3: + version "3.2.0" + resolved "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz" + integrity sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA== + dependencies: + d3-path "^3.1.0" + +d3-shape@^1.2.0: + version "1.3.7" + resolved "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz" + integrity sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw== + dependencies: + d3-path "1" + +"d3-time-format@2 - 4", d3-time-format@4: + version "4.1.0" + resolved "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz" + integrity sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg== + dependencies: + d3-time "1 - 3" + +"d3-time@1 - 3", "d3-time@2.1.1 - 3", d3-time@3: + version "3.1.0" + resolved "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz" + integrity sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q== + dependencies: + d3-array "2 - 3" + +"d3-timer@1 - 3", d3-timer@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz" + integrity sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA== + +"d3-transition@2 - 3", d3-transition@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz" + integrity sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w== + dependencies: + d3-color "1 - 3" + d3-dispatch "1 - 3" + d3-ease "1 - 3" + d3-interpolate "1 - 3" + d3-timer "1 - 3" + +d3-zoom@3: + version "3.0.0" + resolved "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz" + integrity sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw== + dependencies: + d3-dispatch "1 - 3" + d3-drag "2 - 3" + d3-interpolate "1 - 3" + d3-selection "2 - 3" + d3-transition "2 - 3" + +d3@^7.0.0, d3@^7.9.0: + version "7.9.0" + resolved "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz" + integrity sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA== + dependencies: + d3-array "3" + d3-axis "3" + d3-brush "3" + d3-chord "3" + d3-color "3" + d3-contour "4" + d3-delaunay "6" + d3-dispatch "3" + d3-drag "3" + d3-dsv "3" + d3-ease "3" + d3-fetch "3" + d3-force "3" + d3-format "3" + d3-geo "3" + d3-hierarchy "3" + d3-interpolate "3" + d3-path "3" + d3-polygon "3" + d3-quadtree "3" + d3-random "3" + d3-scale "4" + d3-scale-chromatic "3" + d3-selection "3" + d3-shape "3" + d3-time "3" + d3-time-format "4" + d3-timer "3" + d3-transition "3" + d3-zoom "3" + +dagre-d3-es@7.0.11: + version "7.0.11" + resolved "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.11.tgz" + integrity sha512-tvlJLyQf834SylNKax8Wkzco/1ias1OPw8DcUMDE7oUIoSEW25riQVuiu/0OWEFqT0cxHT3Pa9/D82Jr47IONw== + dependencies: + d3 "^7.9.0" + lodash-es "^4.17.21" + +dayjs@^1.11.13: + version "1.11.13" + resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz" + integrity sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg== + +debug@^4.4.0: + version "4.4.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.1.tgz#e5a8bc6cbc4c6cd3e64308b0693a3d4fa550189b" + integrity sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ== + dependencies: + ms "^2.1.3" + +defu@^6.1.4: + version "6.1.4" + resolved "https://registry.yarnpkg.com/defu/-/defu-6.1.4.tgz#4e0c9cf9ff68fe5f3d7f2765cc1a012dfdcb0479" + integrity sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg== + +delaunator@5: + version "5.0.0" + resolved "https://registry.npmjs.org/delaunator/-/delaunator-5.0.0.tgz" + integrity sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw== + dependencies: + robust-predicates "^3.0.0" + +dequal@^2.0.0: + version "2.0.3" + resolved "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz" + integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== + +devlop@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz" + integrity sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA== + dependencies: + dequal "^2.0.0" + +dompurify@^3.2.5: + version "3.2.6" + resolved "https://registry.npmjs.org/dompurify/-/dompurify-3.2.6.tgz" + integrity sha512-/2GogDQlohXPZe6D6NOgQvXLPSYBqIWMnZ8zzOhn09REE4eyAzb+Hed3jhoM9OkuaJ8P6ZGTTVWQKAi8ieIzfQ== + optionalDependencies: + "@types/trusted-types" "^2.0.7" + +entities@^4.5.0: + version "4.5.0" + resolved "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz" + integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== + +esbuild@^0.21.3: + version "0.21.5" + resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz" + integrity sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw== + optionalDependencies: + "@esbuild/aix-ppc64" "0.21.5" + "@esbuild/android-arm" "0.21.5" + "@esbuild/android-arm64" "0.21.5" + "@esbuild/android-x64" "0.21.5" + "@esbuild/darwin-arm64" "0.21.5" + "@esbuild/darwin-x64" "0.21.5" + "@esbuild/freebsd-arm64" "0.21.5" + "@esbuild/freebsd-x64" "0.21.5" + "@esbuild/linux-arm" "0.21.5" + "@esbuild/linux-arm64" "0.21.5" + "@esbuild/linux-ia32" "0.21.5" + "@esbuild/linux-loong64" "0.21.5" + "@esbuild/linux-mips64el" "0.21.5" + "@esbuild/linux-ppc64" "0.21.5" + "@esbuild/linux-riscv64" "0.21.5" + "@esbuild/linux-s390x" "0.21.5" + "@esbuild/linux-x64" "0.21.5" + "@esbuild/netbsd-x64" "0.21.5" + "@esbuild/openbsd-x64" "0.21.5" + "@esbuild/sunos-x64" "0.21.5" + "@esbuild/win32-arm64" "0.21.5" + "@esbuild/win32-ia32" "0.21.5" + "@esbuild/win32-x64" "0.21.5" + +estree-walker@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz" + integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== + +exsolve@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/exsolve/-/exsolve-1.0.7.tgz#3b74e4c7ca5c5f9a19c3626ca857309fa99f9e9e" + integrity sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw== + +focus-trap@^7.6.0: + version "7.6.0" + resolved "https://registry.npmjs.org/focus-trap/-/focus-trap-7.6.0.tgz" + integrity sha512-1td0l3pMkWJLFipobUcGaf+5DTY4PLDDrcqoSaKP8ediO/CoWCCYk/fT/Y2A4e6TNB+Sh6clRJCjOPPnKoNHnQ== + dependencies: + tabbable "^6.2.0" + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +fsevents@~2.3.3: + version "2.3.3" + resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +globals@^15.14.0: + version "15.15.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-15.15.0.tgz#7c4761299d41c32b075715a4ce1ede7897ff72a8" + integrity sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg== + +hachure-fill@^0.5.2: + version "0.5.2" + resolved "https://registry.npmjs.org/hachure-fill/-/hachure-fill-0.5.2.tgz" + integrity sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg== + +hast-util-to-html@^9.0.3: + version "9.0.3" + resolved "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.3.tgz" + integrity sha512-M17uBDzMJ9RPCqLMO92gNNUDuBSq10a25SDBI08iCCxmorf4Yy6sYHK57n9WAbRAAaU+DuR4W6GN9K4DFZesYg== + dependencies: + "@types/hast" "^3.0.0" + "@types/unist" "^3.0.0" + ccount "^2.0.0" + comma-separated-tokens "^2.0.0" + hast-util-whitespace "^3.0.0" + html-void-elements "^3.0.0" + mdast-util-to-hast "^13.0.0" + property-information "^6.0.0" + space-separated-tokens "^2.0.0" + stringify-entities "^4.0.0" + zwitch "^2.0.4" + +hast-util-whitespace@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz" + integrity sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw== + dependencies: + "@types/hast" "^3.0.0" + +hookable@^5.5.3: + version "5.5.3" + resolved "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz" + integrity sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ== + +html-void-elements@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz" + integrity sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg== + +iconv-lite@0.6: + version "0.6.3" + resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +"internmap@1 - 2": + version "2.0.3" + resolved "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz" + integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg== + +internmap@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz" + integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw== + +is-what@^4.1.8: + version "4.1.16" + resolved "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz" + integrity sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A== + +katex@^0.16.22: + version "0.16.22" + resolved "https://registry.npmjs.org/katex/-/katex-0.16.22.tgz" + integrity sha512-XCHRdUw4lf3SKBaJe4EvgqIuWwkPSo9XoeO8GjQW94Bp7TWv9hNhzZjZ+OH9yf1UmLygb7DIT5GSFQiyt16zYg== + dependencies: + commander "^8.3.0" + +khroma@^2.0.0, khroma@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz" + integrity sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw== + +kolorist@^1.8.0: + version "1.8.0" + resolved "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz" + integrity sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ== + +langium@3.3.1: + version "3.3.1" + resolved "https://registry.npmjs.org/langium/-/langium-3.3.1.tgz" + integrity sha512-QJv/h939gDpvT+9SiLVlY7tZC3xB2qK57v0J04Sh9wpMb6MP1q8gB21L3WIo8T5P1MSMg3Ep14L7KkDCFG3y4w== + dependencies: + chevrotain "~11.0.3" + chevrotain-allstar "~0.3.0" + vscode-languageserver "~9.0.1" + vscode-languageserver-textdocument "~1.0.11" + vscode-uri "~3.0.8" + +layout-base@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz" + integrity sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg== + +layout-base@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/layout-base/-/layout-base-2.0.1.tgz" + integrity sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg== + +local-pkg@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/local-pkg/-/local-pkg-1.1.1.tgz#f5fe74a97a3bd3c165788ee08ca9fbe998dc58dd" + integrity sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg== + dependencies: + mlly "^1.7.4" + pkg-types "^2.0.1" + quansync "^0.2.8" + +lodash-es@4.17.21, lodash-es@^4.17.21: + version "4.17.21" + resolved "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz" + integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== + +lucide-vue-next@^0.503.0: + version "0.503.0" + resolved "https://registry.yarnpkg.com/lucide-vue-next/-/lucide-vue-next-0.503.0.tgz#a66bd31fdf84d4ddc590d8a5cb518b5a7da849ec" + integrity sha512-3MrtHIBdh4dPCUZDLxQnvmQ17UzUnBYgezUSIo87Laais8hOz6qIPllp0iG/uS/UIzk7bJxyZRzoZTW/gLSr4A== + +magic-string@^0.30.11: + version "0.30.11" + resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz" + integrity sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A== + dependencies: + "@jridgewell/sourcemap-codec" "^1.5.0" + +magic-string@^0.30.17: + version "0.30.17" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.17.tgz#450a449673d2460e5bbcfba9a61916a1714c7453" + integrity sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA== + dependencies: + "@jridgewell/sourcemap-codec" "^1.5.0" + +mark.js@8.11.1: + version "8.11.1" + resolved "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz" + integrity sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ== + +markdown-it-link-attributes@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/markdown-it-link-attributes/-/markdown-it-link-attributes-4.0.1.tgz#25751f2cf74fd91f0a35ba7b3247fa45f2056d88" + integrity sha512-pg5OK0jPLg62H4k7M9mRJLT61gUp9nvG0XveKYHMOOluASo9OEF13WlXrpAp2aj35LbedAy3QOCgQCw0tkLKAQ== + +marked@^16.0.0: + version "16.1.1" + resolved "https://registry.npmjs.org/marked/-/marked-16.1.1.tgz" + integrity sha512-ij/2lXfCRT71L6u0M29tJPhP0bM5shLL3u5BePhFwPELj2blMJ6GDtD7PfJhRLhJ/c2UwrK17ySVcDzy2YHjHQ== + +mdast-util-to-hast@^13.0.0: + version "13.2.0" + resolved "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz" + integrity sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA== + dependencies: + "@types/hast" "^3.0.0" + "@types/mdast" "^4.0.0" + "@ungap/structured-clone" "^1.0.0" + devlop "^1.0.0" + micromark-util-sanitize-uri "^2.0.0" + trim-lines "^3.0.0" + unist-util-position "^5.0.0" + unist-util-visit "^5.0.0" + vfile "^6.0.0" + +mermaid@^11.8.1: + version "11.9.0" + resolved "https://registry.npmjs.org/mermaid/-/mermaid-11.9.0.tgz" + integrity sha512-YdPXn9slEwO0omQfQIsW6vS84weVQftIyyTGAZCwM//MGhPzL1+l6vO6bkf0wnP4tHigH1alZ5Ooy3HXI2gOag== + dependencies: + "@braintree/sanitize-url" "^7.0.4" + "@iconify/utils" "^2.1.33" + "@mermaid-js/parser" "^0.6.2" + "@types/d3" "^7.4.3" + cytoscape "^3.29.3" + cytoscape-cose-bilkent "^4.1.0" + cytoscape-fcose "^2.2.0" + d3 "^7.9.0" + d3-sankey "^0.12.3" + dagre-d3-es "7.0.11" + dayjs "^1.11.13" + dompurify "^3.2.5" + katex "^0.16.22" + khroma "^2.1.0" + lodash-es "^4.17.21" + marked "^16.0.0" + roughjs "^4.6.6" + stylis "^4.3.6" + ts-dedent "^2.2.0" + uuid "^11.1.0" + +micromark-util-character@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz" + integrity sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ== + dependencies: + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-util-encode@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz" + integrity sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA== + +micromark-util-sanitize-uri@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz" + integrity sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw== + dependencies: + micromark-util-character "^2.0.0" + micromark-util-encode "^2.0.0" + micromark-util-symbol "^2.0.0" + +micromark-util-symbol@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz" + integrity sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw== + +micromark-util-types@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz" + integrity sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w== + +minisearch@^7.1.0: + version "7.1.0" + resolved "https://registry.npmjs.org/minisearch/-/minisearch-7.1.0.tgz" + integrity sha512-tv7c/uefWdEhcu6hvrfTihflgeEi2tN6VV7HJnCjK6VxM75QQJh4t9FwJCsA2EsRS8LCnu3W87CuGPWMocOLCA== + +mitt@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz" + integrity sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw== + +mlly@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/mlly/-/mlly-1.7.4.tgz#3d7295ea2358ec7a271eaa5d000a0f84febe100f" + integrity sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw== + dependencies: + acorn "^8.14.0" + pathe "^2.0.1" + pkg-types "^1.3.0" + ufo "^1.5.4" + +ms@^2.1.3: + version "2.1.3" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +nanoid@^3.3.11: + version "3.3.11" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b" + integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w== + +nanoid@^3.3.7: + version "3.3.8" + resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz" + integrity sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w== + +non-layered-tidy-tree-layout@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/non-layered-tidy-tree-layout/-/non-layered-tidy-tree-layout-2.0.2.tgz" + integrity sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw== + +ohash@^2.0.11: + version "2.0.11" + resolved "https://registry.yarnpkg.com/ohash/-/ohash-2.0.11.tgz#60b11e8cff62ca9dee88d13747a5baa145f5900b" + integrity sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ== + +oniguruma-to-js@0.4.3: + version "0.4.3" + resolved "https://registry.npmjs.org/oniguruma-to-js/-/oniguruma-to-js-0.4.3.tgz" + integrity sha512-X0jWUcAlxORhOqqBREgPMgnshB7ZGYszBNspP+tS9hPD3l13CdaXcHbgImoHUHlrvGx/7AvFEkTRhAGYh+jzjQ== + dependencies: + regex "^4.3.2" + +package-manager-detector@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/package-manager-detector/-/package-manager-detector-1.3.0.tgz#b42d641c448826e03c2b354272456a771ce453c0" + integrity sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ== + +path-data-parser@0.1.0, path-data-parser@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/path-data-parser/-/path-data-parser-0.1.0.tgz" + integrity sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w== + +pathe@^2.0.1, pathe@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/pathe/-/pathe-2.0.3.tgz#3ecbec55421685b70a9da872b2cff3e1cbed1716" + integrity sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w== + +perfect-debounce@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz" + integrity sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA== + +picocolors@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz" + integrity sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw== + +picocolors@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== + +pkg-types@^1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-1.3.1.tgz#bd7cc70881192777eef5326c19deb46e890917df" + integrity sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ== + dependencies: + confbox "^0.1.8" + mlly "^1.7.4" + pathe "^2.0.1" + +pkg-types@^2.0.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-2.2.0.tgz#049bf404f82a66c465200149457acf0c5fb0fb2d" + integrity sha512-2SM/GZGAEkPp3KWORxQZns4M+WSeXbC2HEvmOIJe3Cmiv6ieAJvdVhDldtHqM5J1Y7MrR1XhkBT/rMlhh9FdqQ== + dependencies: + confbox "^0.2.2" + exsolve "^1.0.7" + pathe "^2.0.3" + +points-on-curve@0.2.0, points-on-curve@^0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/points-on-curve/-/points-on-curve-0.2.0.tgz" + integrity sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A== + +points-on-path@^0.2.1: + version "0.2.1" + resolved "https://registry.npmjs.org/points-on-path/-/points-on-path-0.2.1.tgz" + integrity sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g== + dependencies: + path-data-parser "0.1.0" + points-on-curve "0.2.0" + +postcss@^8.4.43, postcss@^8.4.47: + version "8.4.47" + resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz" + integrity sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ== + dependencies: + nanoid "^3.3.7" + picocolors "^1.1.0" + source-map-js "^1.2.1" + +postcss@^8.5.6: + version "8.5.6" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.6.tgz#2825006615a619b4f62a9e7426cc120b349a8f3c" + integrity sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg== + dependencies: + nanoid "^3.3.11" + picocolors "^1.1.1" + source-map-js "^1.2.1" + +preact@^10.0.0: + version "10.16.0" + resolved "https://registry.npmjs.org/preact/-/preact-10.16.0.tgz" + integrity sha512-XTSj3dJ4roKIC93pald6rWuB2qQJO9gO2iLLyTe87MrjQN+HklueLsmskbywEWqCHlclgz3/M4YLL2iBr9UmMA== + +property-information@^6.0.0: + version "6.5.0" + resolved "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz" + integrity sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig== + +quansync@^0.2.8: + version "0.2.10" + resolved "https://registry.yarnpkg.com/quansync/-/quansync-0.2.10.tgz#32053cf166fa36511aae95fc49796116f2dc20e1" + integrity sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A== + +regex@^4.3.2: + version "4.3.2" + resolved "https://registry.npmjs.org/regex/-/regex-4.3.2.tgz" + integrity sha512-kK/AA3A9K6q2js89+VMymcboLOlF5lZRCYJv3gzszXFHBr6kO6qLGzbm+UIugBEV8SMMKCTR59txoY6ctRHYVw== + +reka-ui@^2.2.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/reka-ui/-/reka-ui-2.3.2.tgz#aedae51d85dcc61e418f12ffc0b013fccd5bb00c" + integrity sha512-lCysSCILH2uqShEnt93/qzlXnB7ySvK7scR0Q5C+a2iXwFVzHhvZQsMaSnbQYueoCihx6yyUZTYECepnmKrbRA== + dependencies: + "@floating-ui/dom" "^1.6.13" + "@floating-ui/vue" "^1.1.6" + "@internationalized/date" "^3.5.0" + "@internationalized/number" "^3.5.0" + "@tanstack/vue-virtual" "^3.12.0" + "@vueuse/core" "^12.5.0" + "@vueuse/shared" "^12.5.0" + aria-hidden "^1.2.4" + defu "^6.1.4" + ohash "^2.0.11" + +rfdc@^1.4.1: + version "1.4.1" + resolved "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz" + integrity sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA== + +robust-predicates@^3.0.0: + version "3.0.2" + resolved "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz" + integrity sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg== + +rollup@^4.20.0: + version "4.22.4" + resolved "https://registry.npmjs.org/rollup/-/rollup-4.22.4.tgz" + integrity sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A== + dependencies: + "@types/estree" "1.0.5" + optionalDependencies: + "@rollup/rollup-android-arm-eabi" "4.22.4" + "@rollup/rollup-android-arm64" "4.22.4" + "@rollup/rollup-darwin-arm64" "4.22.4" + "@rollup/rollup-darwin-x64" "4.22.4" + "@rollup/rollup-linux-arm-gnueabihf" "4.22.4" + "@rollup/rollup-linux-arm-musleabihf" "4.22.4" + "@rollup/rollup-linux-arm64-gnu" "4.22.4" + "@rollup/rollup-linux-arm64-musl" "4.22.4" + "@rollup/rollup-linux-powerpc64le-gnu" "4.22.4" + "@rollup/rollup-linux-riscv64-gnu" "4.22.4" + "@rollup/rollup-linux-s390x-gnu" "4.22.4" + "@rollup/rollup-linux-x64-gnu" "4.22.4" + "@rollup/rollup-linux-x64-musl" "4.22.4" + "@rollup/rollup-win32-arm64-msvc" "4.22.4" + "@rollup/rollup-win32-ia32-msvc" "4.22.4" + "@rollup/rollup-win32-x64-msvc" "4.22.4" + fsevents "~2.3.2" + +roughjs@^4.6.6: + version "4.6.6" + resolved "https://registry.npmjs.org/roughjs/-/roughjs-4.6.6.tgz" + integrity sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ== + dependencies: + hachure-fill "^0.5.2" + path-data-parser "^0.1.0" + points-on-curve "^0.2.0" + points-on-path "^0.2.1" + +rw@1: + version "1.3.3" + resolved "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz" + integrity sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ== + +"safer-buffer@>= 2.1.2 < 3.0.0": + version "2.1.2" + resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +shiki@1.22.2, shiki@^1.22.2: + version "1.22.2" + resolved "https://registry.npmjs.org/shiki/-/shiki-1.22.2.tgz" + integrity sha512-3IZau0NdGKXhH2bBlUk4w1IHNxPh6A5B2sUpyY+8utLu2j/h1QpFkAaUA1bAMxOWWGtTWcAh531vnS4NJKS/lA== + dependencies: + "@shikijs/core" "1.22.2" + "@shikijs/engine-javascript" "1.22.2" + "@shikijs/engine-oniguruma" "1.22.2" + "@shikijs/types" "1.22.2" + "@shikijs/vscode-textmate" "^9.3.0" + "@types/hast" "^3.0.4" + +source-map-js@^1.2.0, source-map-js@^1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz" + integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== + +source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0: + version "0.6.1" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +space-separated-tokens@^2.0.0: + version "2.0.2" + resolved "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz" + integrity sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q== + +speakingurl@^14.0.1: + version "14.0.1" + resolved "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz" + integrity sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ== + +stringify-entities@^4.0.0: + version "4.0.4" + resolved "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz" + integrity sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg== + dependencies: + character-entities-html4 "^2.0.0" + character-entities-legacy "^3.0.0" + +stylis@^4.3.6: + version "4.3.6" + resolved "https://registry.npmjs.org/stylis/-/stylis-4.3.6.tgz" + integrity sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ== + +superjson@^2.2.1: + version "2.2.1" + resolved "https://registry.npmjs.org/superjson/-/superjson-2.2.1.tgz" + integrity sha512-8iGv75BYOa0xRJHK5vRLEjE2H/i4lulTjzpUXic3Eg8akftYjkmQDa8JARQ42rlczXyFR3IeRoeFCc7RxHsYZA== + dependencies: + copy-anything "^3.0.2" + +tabbable@^6.2.0: + version "6.2.0" + resolved "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz" + integrity sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew== + +terser@^5.43.1: + version "5.43.1" + resolved "https://registry.npmjs.org/terser/-/terser-5.43.1.tgz" + integrity sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg== + dependencies: + "@jridgewell/source-map" "^0.3.3" + acorn "^8.14.0" + commander "^2.20.0" + source-map-support "~0.5.20" + +tinyexec@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tinyexec/-/tinyexec-1.0.1.tgz#70c31ab7abbb4aea0a24f55d120e5990bfa1e0b1" + integrity sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw== + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + +trim-lines@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz" + integrity sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg== + +ts-dedent@^2.2.0: + version "2.2.0" + resolved "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz" + integrity sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ== + +tslib@^2.0.0, tslib@^2.8.0: + version "2.8.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== + +ufo@^1.5.4: + version "1.6.1" + resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.6.1.tgz#ac2db1d54614d1b22c1d603e3aef44a85d8f146b" + integrity sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA== + +unist-util-is@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz" + integrity sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw== + dependencies: + "@types/unist" "^3.0.0" + +unist-util-position@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz" + integrity sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA== + dependencies: + "@types/unist" "^3.0.0" + +unist-util-stringify-position@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz" + integrity sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ== + dependencies: + "@types/unist" "^3.0.0" + +unist-util-visit-parents@^6.0.0: + version "6.0.1" + resolved "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz" + integrity sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw== + dependencies: + "@types/unist" "^3.0.0" + unist-util-is "^6.0.0" + +unist-util-visit@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz" + integrity sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg== + dependencies: + "@types/unist" "^3.0.0" + unist-util-is "^6.0.0" + unist-util-visit-parents "^6.0.0" + +uuid@^11.1.0: + version "11.1.0" + resolved "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz" + integrity sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A== + +vfile-message@^4.0.0: + version "4.0.2" + resolved "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz" + integrity sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw== + dependencies: + "@types/unist" "^3.0.0" + unist-util-stringify-position "^4.0.0" + +vfile@^6.0.0: + version "6.0.3" + resolved "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz" + integrity sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q== + dependencies: + "@types/unist" "^3.0.0" + vfile-message "^4.0.0" + +vite@^5.4.10: + version "5.4.19" + resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.19.tgz#20efd060410044b3ed555049418a5e7d1998f959" + integrity sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA== + dependencies: + esbuild "^0.21.3" + postcss "^8.4.43" + rollup "^4.20.0" + optionalDependencies: + fsevents "~2.3.3" + +vitepress-openapi@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/vitepress-openapi/-/vitepress-openapi-0.1.3.tgz#7ef64c2e559514845207821fc69e47e12ddd262f" + integrity sha512-3p/Mc3eActjtSaIQNMNihXUSoLLoPxlG2MYwWWMw3D3eBDfreDfMbhNwQc/AtCUBIxinhgnn/LXYEEI3C/PxgQ== + dependencies: + "@vueuse/core" "^13.1.0" + class-variance-authority "^0.7.1" + clsx "^2.1.1" + lucide-vue-next "^0.503.0" + markdown-it-link-attributes "^4.0.1" + reka-ui "^2.2.0" + +vitepress-plugin-mermaid@^2.0.17: + version "2.0.17" + resolved "https://registry.npmjs.org/vitepress-plugin-mermaid/-/vitepress-plugin-mermaid-2.0.17.tgz" + integrity sha512-IUzYpwf61GC6k0XzfmAmNrLvMi9TRrVRMsUyCA8KNXhg/mQ1VqWnO0/tBVPiX5UoKF1mDUwqn5QV4qAJl6JnUg== + optionalDependencies: + "@mermaid-js/mermaid-mindmap" "^9.3.0" + +vitepress@^1.5.0: + version "1.5.0" + resolved "https://registry.npmjs.org/vitepress/-/vitepress-1.5.0.tgz" + integrity sha512-q4Q/G2zjvynvizdB3/bupdYkCJe2umSAMv9Ju4d92E6/NXJ59z70xB0q5p/4lpRyAwflDsbwy1mLV9Q5+nlB+g== + dependencies: + "@docsearch/css" "^3.6.2" + "@docsearch/js" "^3.6.2" + "@iconify-json/simple-icons" "^1.2.10" + "@shikijs/core" "^1.22.2" + "@shikijs/transformers" "^1.22.2" + "@shikijs/types" "^1.22.2" + "@types/markdown-it" "^14.1.2" + "@vitejs/plugin-vue" "^5.1.4" + "@vue/devtools-api" "^7.5.4" + "@vue/shared" "^3.5.12" + "@vueuse/core" "^11.1.0" + "@vueuse/integrations" "^11.1.0" + focus-trap "^7.6.0" + mark.js "8.11.1" + minisearch "^7.1.0" + shiki "^1.22.2" + vite "^5.4.10" + vue "^3.5.12" + +vscode-jsonrpc@8.2.0: + version "8.2.0" + resolved "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz" + integrity sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA== + +vscode-languageserver-protocol@3.17.5: + version "3.17.5" + resolved "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz" + integrity sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg== + dependencies: + vscode-jsonrpc "8.2.0" + vscode-languageserver-types "3.17.5" + +vscode-languageserver-textdocument@~1.0.11: + version "1.0.12" + resolved "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz" + integrity sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA== + +vscode-languageserver-types@3.17.5: + version "3.17.5" + resolved "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz" + integrity sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg== + +vscode-languageserver@~9.0.1: + version "9.0.1" + resolved "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz" + integrity sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g== + dependencies: + vscode-languageserver-protocol "3.17.5" + +vscode-uri@~3.0.8: + version "3.0.8" + resolved "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz" + integrity sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw== + +vue-demi@>=0.13.0, vue-demi@>=0.14.10: + version "0.14.10" + resolved "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz" + integrity sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg== + +vue@^3.5.12: + version "3.5.12" + resolved "https://registry.npmjs.org/vue/-/vue-3.5.12.tgz" + integrity sha512-CLVZtXtn2ItBIi/zHZ0Sg1Xkb7+PU32bJJ8Bmy7ts3jxXTcbfsEfBivFYYWz1Hur+lalqGAh65Coin0r+HRUfg== + dependencies: + "@vue/compiler-dom" "3.5.12" + "@vue/compiler-sfc" "3.5.12" + "@vue/runtime-dom" "3.5.12" + "@vue/server-renderer" "3.5.12" + "@vue/shared" "3.5.12" + +vue@^3.5.13: + version "3.5.18" + resolved "https://registry.yarnpkg.com/vue/-/vue-3.5.18.tgz#3d622425ad1391a2b0138323211ec784f4415686" + integrity sha512-7W4Y4ZbMiQ3SEo+m9lnoNpV9xG7QVMLa+/0RFwwiAVkeYoyGXqWE85jabU4pllJNUzqfLShJ5YLptewhCWUgNA== + dependencies: + "@vue/compiler-dom" "3.5.18" + "@vue/compiler-sfc" "3.5.18" + "@vue/runtime-dom" "3.5.18" + "@vue/server-renderer" "3.5.18" + "@vue/shared" "3.5.18" + +zwitch@^2.0.4: + version "2.0.4" + resolved "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz" + integrity sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A== diff --git a/execution/evm/README.md b/execution/evm/README.md index 77cc0e737c..b44ea71b01 100644 --- a/execution/evm/README.md +++ b/execution/evm/README.md @@ -1,6 +1,6 @@ # Go Execution EVM -This repository implements the `execution.Executor` interface from `github.com/evstack/ev-node/core/execution` (currently on feature branch `feature/exec_api`). It provides a pure Engine API-based execution client for Rollkit. +This repository implements the `execution.Executor` interface from `github.com/evstack/ev-node/core/execution` (currently on feature branch `feature/exec_api`). It provides a pure Engine API-based execution client for Evolve. ## EngineClient Implementation @@ -9,9 +9,9 @@ The `EngineClient` is a 100% Engine API compatible implementation of the `execut ### Genesis and initial height In the context of the EVM, the genesis block is designated as a unique block with the block number `0`. -To ensure compatibility with both rollkit and the EVM, the only permissible initial height is `1`. +To ensure compatibility with both evolve and the EVM, the only permissible initial height is `1`. During `InitChain` EVM genesis block is acknowledged (at height 0), and empty block is created (at height 1). -This approach ensures that the block numbers between the EVM and rollkit remain consistent and synchronized. +This approach ensures that the block numbers between the EVM and evolve remain consistent and synchronized. ### Genesis Requirements @@ -89,13 +89,13 @@ This allows the client to interact with the execution layer for read operations ```mermaid graph LR - subgraph Rollkit Binary - RollkitCore[Rollkit Core] + subgraph Evolve Binary + EvolveCore[Evolve Core] PureEngineClient[PureEngineClient] end %% Connections - RollkitCore --> PureEngineClient + EvolveCore --> PureEngineClient PureEngineClient -->|Engine API| Reth PureEngineClient -->|Eth API| Reth diff --git a/execution/evm/execution.go b/execution/evm/execution.go index 71cb53f89c..f2e37ae238 100644 --- a/execution/evm/execution.go +++ b/execution/evm/execution.go @@ -147,7 +147,7 @@ func (c *EngineClient) GetTxs(ctx context.Context) ([][]byte, error) { // ExecuteTxs executes the given transactions at the specified block height and timestamp func (c *EngineClient) ExecuteTxs(ctx context.Context, txs [][]byte, blockHeight uint64, timestamp time.Time, prevStateRoot []byte) (updatedStateRoot []byte, maxBytes uint64, err error) { - // convert rollkit tx to hex strings for rollkit-reth + // convert evolve tx to hex strings for ev-reth txsPayload := make([]string, len(txs)) for i, tx := range txs { // Use the raw transaction bytes directly instead of re-encoding @@ -168,23 +168,23 @@ func (c *EngineClient) ExecuteTxs(ctx context.Context, txs [][]byte, blockHeight // update forkchoice to get the next payload id var forkchoiceResult engine.ForkChoiceResponse - // Create rollkit-compatible payload attributes with flattened structure - rollkitPayloadAttrs := map[string]interface{}{ + // Create evolve-compatible payload attributes with flattened structure + evPayloadAttrs := map[string]interface{}{ // Standard Ethereum payload attributes (flattened) - using camelCase as expected by JSON "timestamp": timestamp.Unix(), "prevRandao": c.derivePrevRandao(blockHeight), "suggestedFeeRecipient": c.feeRecipient, "withdrawals": []*types.Withdrawal{}, // V3 requires parentBeaconBlockRoot - "parentBeaconBlockRoot": common.Hash{}.Hex(), // Use zero hash for rollkit - // Rollkit-specific fields + "parentBeaconBlockRoot": common.Hash{}.Hex(), // Use zero hash for evolve + // evolve-specific fields "transactions": txsPayload, "gasLimit": prevGasLimit, // Use camelCase to match JSON conventions } err = c.engineClient.CallContext(ctx, &forkchoiceResult, "engine_forkchoiceUpdatedV3", args, - rollkitPayloadAttrs, + evPayloadAttrs, ) if err != nil { return nil, 0, fmt.Errorf("forkchoice update failed: %w", err) diff --git a/execution/evm/execution_test.go b/execution/evm/execution_test.go index 76b468fafc..b2ab5bf9e2 100644 --- a/execution/evm/execution_test.go +++ b/execution/evm/execution_test.go @@ -59,7 +59,7 @@ func TestEngineExecution(t *testing.T) { genesisHash := common.HexToHash(GENESIS_HASH) genesisTime := time.Now().UTC().Truncate(time.Second) genesisStateRoot := common.HexToHash(GENESIS_STATEROOT) - rollkitGenesisStateRoot := genesisStateRoot[:] + GenesisStateRoot := genesisStateRoot[:] t.Run("Build chain", func(tt *testing.T) { jwtSecret := SetupTestRethEngine(tt, DOCKER_PATH, JWT_FILENAME) @@ -77,10 +77,10 @@ func TestEngineExecution(t *testing.T) { defer cancel() stateRoot, gasLimit, err := executionClient.InitChain(ctx, genesisTime, initialHeight, CHAIN_ID) require.NoError(t, err) - require.Equal(t, rollkitGenesisStateRoot, stateRoot) + require.Equal(t, GenesisStateRoot, stateRoot) require.NotZero(t, gasLimit) - prevStateRoot := rollkitGenesisStateRoot + prevStateRoot := GenesisStateRoot lastHeight, lastHash, lastTxs := checkLatestBlock(tt, ctx) lastNonce := uint64(0) @@ -167,10 +167,10 @@ func TestEngineExecution(t *testing.T) { defer cancel() stateRoot, gasLimit, err := executionClient.InitChain(ctx, genesisTime, initialHeight, CHAIN_ID) require.NoError(t, err) - require.Equal(t, rollkitGenesisStateRoot, stateRoot) + require.Equal(t, GenesisStateRoot, stateRoot) require.NotZero(t, gasLimit) - prevStateRoot := rollkitGenesisStateRoot + prevStateRoot := GenesisStateRoot lastHeight, lastHash, lastTxs := checkLatestBlock(tt, ctx) for blockHeight := initialHeight; blockHeight <= 10; blockHeight++ { diff --git a/execution/grpc/README.md b/execution/grpc/README.md index 10e6f4dc2a..8647b2ad90 100644 --- a/execution/grpc/README.md +++ b/execution/grpc/README.md @@ -1,10 +1,10 @@ # gRPC Execution Client -This package provides a gRPC-based implementation of the Rollkit execution interface. It allows Rollkit to communicate with remote execution clients via gRPC using the Connect-RPC framework. +This package provides a gRPC-based implementation of the Evolve execution interface. It allows Evolve to communicate with remote execution clients via gRPC using the Connect-RPC framework. ## Overview -The gRPC execution client enables separation between the consensus layer (Rollkit) and the execution layer by providing a network interface for communication. This allows execution clients to run in separate processes or even on different machines. +The gRPC execution client enables separation between the consensus layer (Evolve) and the execution layer by providing a network interface for communication. This allows execution clients to run in separate processes or even on different machines. ## Usage @@ -44,7 +44,7 @@ http.ListenAndServe(":50051", handler) ## Protocol -The gRPC service is defined in `proto/rollkit/v1/execution.proto` and provides the following methods: +The gRPC service is defined in `proto/evnode/v1/execution.proto` and provides the following methods: - `InitChain`: Initialize the blockchain with genesis parameters - `GetTxs`: Fetch transactions from the mempool diff --git a/node/full.go b/node/full.go index cba92c7233..e5702d105b 100644 --- a/node/full.go +++ b/node/full.go @@ -28,11 +28,11 @@ import ( "github.com/evstack/ev-node/pkg/service" "github.com/evstack/ev-node/pkg/signer" "github.com/evstack/ev-node/pkg/store" - rollkitsync "github.com/evstack/ev-node/pkg/sync" + evsync "github.com/evstack/ev-node/pkg/sync" ) // prefixes used in KV store to separate rollkit data from execution environment data (if the same data base is reused) -var RollkitPrefix = "0" +var EvPrefix = "0" const ( // genesisChunkSize is the maximum size, in bytes, of each @@ -56,8 +56,8 @@ type FullNode struct { da coreda.DA p2pClient *p2p.Client - hSyncService *rollkitsync.HeaderSyncService - dSyncService *rollkitsync.DataSyncService + hSyncService *evsync.HeaderSyncService + dSyncService *evsync.DataSyncService Store store.Store blockManager *block.Manager reaper *block.Reaper @@ -84,7 +84,7 @@ func newFullNode( ) (fn *FullNode, err error) { seqMetrics, _ := metricsProvider(genesis.ChainID) - mainKV := newPrefixKV(database, RollkitPrefix) + mainKV := newPrefixKV(database, EvPrefix) headerSyncService, err := initHeaderSyncService(mainKV, nodeConfig, genesis, p2pClient, logger) if err != nil { return nil, err @@ -154,8 +154,8 @@ func initHeaderSyncService( genesis genesispkg.Genesis, p2pClient *p2p.Client, logger zerolog.Logger, -) (*rollkitsync.HeaderSyncService, error) { - headerSyncService, err := rollkitsync.NewHeaderSyncService(mainKV, nodeConfig, genesis, p2pClient, logger.With().Str("component", "HeaderSyncService").Logger()) +) (*evsync.HeaderSyncService, error) { + headerSyncService, err := evsync.NewHeaderSyncService(mainKV, nodeConfig, genesis, p2pClient, logger.With().Str("component", "HeaderSyncService").Logger()) if err != nil { return nil, fmt.Errorf("error while initializing HeaderSyncService: %w", err) } @@ -168,8 +168,8 @@ func initDataSyncService( genesis genesispkg.Genesis, p2pClient *p2p.Client, logger zerolog.Logger, -) (*rollkitsync.DataSyncService, error) { - dataSyncService, err := rollkitsync.NewDataSyncService(mainKV, nodeConfig, genesis, p2pClient, logger.With().Str("component", "DataSyncService").Logger()) +) (*evsync.DataSyncService, error) { + dataSyncService, err := evsync.NewDataSyncService(mainKV, nodeConfig, genesis, p2pClient, logger.With().Str("component", "DataSyncService").Logger()) if err != nil { return nil, fmt.Errorf("error while initializing DataSyncService: %w", err) } @@ -194,8 +194,8 @@ func initBlockManager( sequencer coresequencer.Sequencer, da coreda.DA, logger zerolog.Logger, - headerSyncService *rollkitsync.HeaderSyncService, - dataSyncService *rollkitsync.DataSyncService, + headerSyncService *evsync.HeaderSyncService, + dataSyncService *evsync.DataSyncService, seqMetrics *block.Metrics, gasPrice float64, gasMultiplier float64, diff --git a/node/full_node.md b/node/full_node.md index 607fee9112..0192b635ca 100644 --- a/node/full_node.md +++ b/node/full_node.md @@ -2,7 +2,7 @@ ## Abstract -A Full Node is a top-level service that encapsulates different components of Rollkit and initializes/manages them. +A Full Node is a top-level service that encapsulates different components of Evolve and initializes/manages them. ## Details diff --git a/node/full_node_integration_test.go b/node/full_node_integration_test.go index d2407985e2..708e19d4cd 100644 --- a/node/full_node_integration_test.go +++ b/node/full_node_integration_test.go @@ -10,7 +10,7 @@ import ( "github.com/stretchr/testify/require" coreexecutor "github.com/evstack/ev-node/core/execution" - rollkitconfig "github.com/evstack/ev-node/pkg/config" + evconfig "github.com/evstack/ev-node/pkg/config" ) // TestTxGossipingMultipleNodesNoDA tests that transactions are gossiped and blocks are sequenced and synced across multiple nodes without the DA layer over P2P. @@ -19,7 +19,7 @@ func TestTxGossipingMultipleNodesNoDA(t *testing.T) { require := require.New(t) config := getTestConfig(t, 1) // Set the DA block time to a very large value to ensure that the DA layer is not used - config.DA.BlockTime = rollkitconfig.DurationWrapper{Duration: 100 * time.Second} + config.DA.BlockTime = evconfig.DurationWrapper{Duration: 100 * time.Second} numNodes := 3 nodes, cleanups := createNodesWithCleanup(t, numNodes, config) for _, cleanup := range cleanups { @@ -124,8 +124,8 @@ func TestFastDASync(t *testing.T) { config := getTestConfig(t, 1) // Set the block time to 2 seconds and the DA block time to 1 second // Note: these are large values to avoid test failures due to slow CI machines - config.Node.BlockTime = rollkitconfig.DurationWrapper{Duration: 2 * time.Second} - config.DA.BlockTime = rollkitconfig.DurationWrapper{Duration: 1 * time.Second} + config.Node.BlockTime = evconfig.DurationWrapper{Duration: 2 * time.Second} + config.DA.BlockTime = evconfig.DurationWrapper{Duration: 1 * time.Second} nodes, cleanups := createNodesWithCleanup(t, 2, config) for _, cleanup := range cleanups { @@ -168,8 +168,8 @@ func TestSingleSequencerTwoFullNodesBlockSyncSpeed(t *testing.T) { // Set up three nodes: 1 sequencer, 2 full nodes config := getTestConfig(t, 1) - config.Node.BlockTime = rollkitconfig.DurationWrapper{Duration: 100 * time.Millisecond} // fast block time - config.DA.BlockTime = rollkitconfig.DurationWrapper{Duration: 10 * time.Second} // slow DA block time + config.Node.BlockTime = evconfig.DurationWrapper{Duration: 100 * time.Millisecond} // fast block time + config.DA.BlockTime = evconfig.DurationWrapper{Duration: 10 * time.Second} // slow DA block time numNodes := 3 nodes, cleanups := createNodesWithCleanup(t, numNodes, config) diff --git a/node/helpers_test.go b/node/helpers_test.go index c28354a820..3d1839f011 100644 --- a/node/helpers_test.go +++ b/node/helpers_test.go @@ -21,7 +21,7 @@ import ( coreexecutor "github.com/evstack/ev-node/core/execution" coresequencer "github.com/evstack/ev-node/core/sequencer" - rollkitconfig "github.com/evstack/ev-node/pkg/config" + evconfig "github.com/evstack/ev-node/pkg/config" "github.com/evstack/ev-node/pkg/p2p" "github.com/evstack/ev-node/pkg/p2p/key" remote_signer "github.com/evstack/ev-node/pkg/signer/noop" @@ -43,7 +43,7 @@ const ( ) // createTestComponents creates test components for node initialization -func createTestComponents(t *testing.T, config rollkitconfig.Config) (coreexecutor.Executor, coresequencer.Sequencer, coreda.DA, *p2p.Client, datastore.Batching, *key.NodeKey, func()) { +func createTestComponents(t *testing.T, config evconfig.Config) (coreexecutor.Executor, coresequencer.Sequencer, coreda.DA, *p2p.Client, datastore.Batching, *key.NodeKey, func()) { executor := coreexecutor.NewDummyExecutor() sequencer := coresequencer.NewDummySequencer() dummyDA := coreda.NewDummyDA(100_000, 0, 0, config.DA.BlockTime.Duration) @@ -68,37 +68,37 @@ func createTestComponents(t *testing.T, config rollkitconfig.Config) (coreexecut return executor, sequencer, dummyDA, p2pClient, ds, p2pKey, stopDAHeightTicker } -func getTestConfig(t *testing.T, n int) rollkitconfig.Config { +func getTestConfig(t *testing.T, n int) evconfig.Config { // Use a higher base port to reduce chances of conflicts with system services startPort := 40000 // Spread port ranges further apart - return rollkitconfig.Config{ + return evconfig.Config{ RootDir: t.TempDir(), - Node: rollkitconfig.NodeConfig{ + Node: evconfig.NodeConfig{ Aggregator: true, - BlockTime: rollkitconfig.DurationWrapper{Duration: 100 * time.Millisecond}, + BlockTime: evconfig.DurationWrapper{Duration: 100 * time.Millisecond}, MaxPendingHeadersAndData: 1000, - LazyBlockInterval: rollkitconfig.DurationWrapper{Duration: 5 * time.Second}, + LazyBlockInterval: evconfig.DurationWrapper{Duration: 5 * time.Second}, }, - DA: rollkitconfig.DAConfig{ - BlockTime: rollkitconfig.DurationWrapper{Duration: 200 * time.Millisecond}, + DA: evconfig.DAConfig{ + BlockTime: evconfig.DurationWrapper{Duration: 200 * time.Millisecond}, Address: MockDAAddress, Namespace: MockDANamespace, }, - P2P: rollkitconfig.P2PConfig{ + P2P: evconfig.P2PConfig{ ListenAddress: fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", startPort+n), }, - RPC: rollkitconfig.RPCConfig{ + RPC: evconfig.RPCConfig{ Address: fmt.Sprintf("127.0.0.1:%d", 8000+n), }, ChainID: "test-chain", - Instrumentation: &rollkitconfig.InstrumentationConfig{}, + Instrumentation: &evconfig.InstrumentationConfig{}, } } // newTestNode is a private helper that creates a node and returns it with a unified cleanup function. func newTestNode( t *testing.T, - config rollkitconfig.Config, + config evconfig.Config, executor coreexecutor.Executor, sequencer coresequencer.Sequencer, dac coreda.DA, @@ -123,7 +123,7 @@ func newTestNode( p2pClient, genesis, ds, - DefaultMetricsProvider(rollkitconfig.DefaultInstrumentationConfig()), + DefaultMetricsProvider(evconfig.DefaultInstrumentationConfig()), zerolog.Nop(), NodeOptions{}, ) @@ -139,14 +139,14 @@ func newTestNode( return node.(*FullNode), cleanup } -func createNodeWithCleanup(t *testing.T, config rollkitconfig.Config) (*FullNode, func()) { +func createNodeWithCleanup(t *testing.T, config evconfig.Config) (*FullNode, func()) { executor, sequencer, dac, p2pClient, ds, _, stopDAHeightTicker := createTestComponents(t, config) return newTestNode(t, config, executor, sequencer, dac, p2pClient, ds, stopDAHeightTicker) } func createNodeWithCustomComponents( t *testing.T, - config rollkitconfig.Config, + config evconfig.Config, executor coreexecutor.Executor, sequencer coresequencer.Sequencer, dac coreda.DA, @@ -158,7 +158,7 @@ func createNodeWithCustomComponents( } // Creates the given number of nodes the given nodes using the given wait group to synchronize them -func createNodesWithCleanup(t *testing.T, num int, config rollkitconfig.Config) ([]*FullNode, []func()) { +func createNodesWithCleanup(t *testing.T, num int, config evconfig.Config) ([]*FullNode, []func()) { t.Helper() require := require.New(t) @@ -188,7 +188,7 @@ func createNodesWithCleanup(t *testing.T, num int, config rollkitconfig.Config) p2pClient, genesis, ds, - DefaultMetricsProvider(rollkitconfig.DefaultInstrumentationConfig()), + DefaultMetricsProvider(evconfig.DefaultInstrumentationConfig()), zerolog.Nop(), NodeOptions{}, ) @@ -226,7 +226,7 @@ func createNodesWithCleanup(t *testing.T, num int, config rollkitconfig.Config) p2pClient, genesis, dssync.MutexWrap(datastore.NewMapDatastore()), - DefaultMetricsProvider(rollkitconfig.DefaultInstrumentationConfig()), + DefaultMetricsProvider(evconfig.DefaultInstrumentationConfig()), zerolog.Nop(), NodeOptions{}, ) diff --git a/node/single_sequencer_integration_test.go b/node/single_sequencer_integration_test.go index 6faa0a06db..ec0f4bdfef 100644 --- a/node/single_sequencer_integration_test.go +++ b/node/single_sequencer_integration_test.go @@ -15,7 +15,7 @@ import ( coreda "github.com/evstack/ev-node/core/da" coreexecutor "github.com/evstack/ev-node/core/execution" - rollkitconfig "github.com/evstack/ev-node/pkg/config" + evconfig "github.com/evstack/ev-node/pkg/config" testutils "github.com/celestiaorg/utils/test" ) @@ -267,7 +267,7 @@ func TestMaxPendingHeadersAndData(t *testing.T) { config.Node.MaxPendingHeadersAndData = 2 // Set DA block time large enough to avoid header submission to DA layer - config.DA.BlockTime = rollkitconfig.DurationWrapper{Duration: 100 * time.Second} + config.DA.BlockTime = evconfig.DurationWrapper{Duration: 100 * time.Second} node, cleanup := createNodeWithCleanup(t, config) defer cleanup() @@ -301,8 +301,8 @@ func TestBatchQueueThrottlingWithDAFailure(t *testing.T) { // Set up configuration with low limits to trigger throttling quickly config := getTestConfig(t, 1) config.Node.MaxPendingHeadersAndData = 3 // Low limit to quickly reach pending limit after DA failure - config.Node.BlockTime = rollkitconfig.DurationWrapper{Duration: 100 * time.Millisecond} - config.DA.BlockTime = rollkitconfig.DurationWrapper{Duration: 1 * time.Second} // Longer DA time to ensure blocks are produced first + config.Node.BlockTime = evconfig.DurationWrapper{Duration: 100 * time.Millisecond} + config.DA.BlockTime = evconfig.DurationWrapper{Duration: 1 * time.Second} // Longer DA time to ensure blocks are produced first // Create test components executor, sequencer, dummyDA, p2pClient, ds, _, stopDAHeightTicker := createTestComponents(t, config) diff --git a/pkg/cmd/README.md b/pkg/cmd/README.md index e2fd616b70..20d53371b5 100644 --- a/pkg/cmd/README.md +++ b/pkg/cmd/README.md @@ -1,26 +1,26 @@ -# Rollkit CLI +# Evolve CLI -A cli tool that allows you to run different kinds of nodes for a rollkit network while also helping you generate the required configuration files +A cli tool that allows you to run different kinds of nodes for a evolve network while also helping you generate the required configuration files ## Install NOTE: Requires Go version >= 1.19. -To install `rollkit`, simply run the following command at the root of the rollkit repo +To install `evolve`, simply run the following command at the root of the evolve repo ```bash make install ``` -The latest Rollkit is now installed. You can verify the installation by running: +The latest Evolve is now installed. You can verify the installation by running: ```bash -rollkit version +evolve version ``` ## Reinstall -If you have Rollkit installed, and you make updates that you want to test, simply run: +If you have Evolve installed, and you make updates that you want to test, simply run: ```bash make install diff --git a/pkg/cmd/keys_test.go b/pkg/cmd/keys_test.go index 6f587138ff..8fd97d9386 100644 --- a/pkg/cmd/keys_test.go +++ b/pkg/cmd/keys_test.go @@ -21,7 +21,7 @@ import ( // setupRootCmd creates a new root command and adds the keys command to it. // This is necessary because the keys commands rely on global flags defined on the root. func setupRootCmd() *cobra.Command { - root := &cobra.Command{Use: "rollkit-test"} + root := &cobra.Command{Use: "evolve-test"} // Prevent cobra from printing errors, so we can assert on them root.SilenceErrors = true // Prevent cobra from printing usage, so we can assert on output diff --git a/pkg/cmd/p2p_test.go b/pkg/cmd/p2p_test.go index 035fc6dd81..5ea9d91b98 100644 --- a/pkg/cmd/p2p_test.go +++ b/pkg/cmd/p2p_test.go @@ -84,7 +84,7 @@ func TestNetInfoCmd_Success(t *testing.T) { httpServer := httptest.NewServer(mux) defer httpServer.Close() - tempDir, err := os.MkdirTemp("", "rollkit-test-home-*") + tempDir, err := os.MkdirTemp("", "evolve-test-home-*") require.NoError(err) defer os.RemoveAll(tempDir) @@ -161,7 +161,7 @@ func TestNetInfoCmd_NoPeers(t *testing.T) { httpServer := httptest.NewServer(mux) defer httpServer.Close() - tempDir, err := os.MkdirTemp("", "rollkit-test-home-nopeer-*") + tempDir, err := os.MkdirTemp("", "evolve-test-home-nopeer-*") require.NoError(err) defer os.RemoveAll(tempDir) diff --git a/pkg/cmd/version.go b/pkg/cmd/version.go index ad0e391422..c6d48f7e2d 100644 --- a/pkg/cmd/version.go +++ b/pkg/cmd/version.go @@ -16,7 +16,7 @@ var ( Version string ) -// VersionCmd is the command to show version info for rollkit CLI +// VersionCmd is the command to show version info for evolve CLI var VersionCmd = &cobra.Command{ Use: "version", Short: "Show version info", @@ -29,8 +29,8 @@ var VersionCmd = &cobra.Command{ } out := cmd.OutOrStdout() w := tabwriter.NewWriter(out, 2, 0, 2, ' ', 0) - _, err1 := fmt.Fprintf(w, "\nrollkit version:\t%v\n", Version) - _, err2 := fmt.Fprintf(w, "rollkit git sha:\t%v\n", GitSHA) + _, err1 := fmt.Fprintf(w, "\nevolve version:\t%v\n", Version) + _, err2 := fmt.Fprintf(w, "evolve git sha:\t%v\n", GitSHA) _, err3 := fmt.Fprintln(w, "") return errors.Join(err1, err2, err3, w.Flush()) }, diff --git a/pkg/config/addr_test.go b/pkg/config/addr_test.go index 3cf95262f0..39eb68d7b9 100644 --- a/pkg/config/addr_test.go +++ b/pkg/config/addr_test.go @@ -12,8 +12,8 @@ func TestTranslateAddresses(t *testing.T) { t.Parallel() invalidCosmos := "foobar" - validCosmos := "127.0.0.1:1234" - validRollkit := "/ip4/127.0.0.1/tcp/1234" + legactIP := "127.0.0.1:1234" + validIP := "/ip4/127.0.0.1/tcp/1234" cases := []struct { name string @@ -24,14 +24,14 @@ func TestTranslateAddresses(t *testing.T) { {"empty", Config{}, Config{}, ""}, { "valid listen address", - Config{P2P: P2PConfig{ListenAddress: validCosmos}}, - Config{P2P: P2PConfig{ListenAddress: validRollkit}}, + Config{P2P: P2PConfig{ListenAddress: legactIP}}, + Config{P2P: P2PConfig{ListenAddress: validIP}}, "", }, { "valid seed address", - Config{P2P: P2PConfig{Peers: validCosmos + "," + validCosmos}}, - Config{P2P: P2PConfig{Peers: validRollkit + "," + validRollkit}}, + Config{P2P: P2PConfig{Peers: legactIP + "," + legactIP}}, + Config{P2P: P2PConfig{Peers: validIP + "," + validIP}}, "", }, { @@ -42,7 +42,7 @@ func TestTranslateAddresses(t *testing.T) { }, { "invalid seed address", - Config{P2P: P2PConfig{Peers: validCosmos + "," + invalidCosmos}}, + Config{P2P: P2PConfig{Peers: legactIP + "," + invalidCosmos}}, Config{}, errInvalidAddress.Error(), }, diff --git a/pkg/config/config.go b/pkg/config/config.go index 8b0a0c9a97..69d5e088e6 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -144,7 +144,7 @@ type Config struct { // DAConfig contains all Data Availability configuration parameters type DAConfig struct { - Address string `mapstructure:"address" yaml:"address" comment:"Address of the data availability layer service (host:port). This is the endpoint where Rollkit will connect to submit and retrieve data."` + Address string `mapstructure:"address" yaml:"address" comment:"Address of the data availability layer service (host:port). This is the endpoint where Evolve will connect to submit and retrieve data."` AuthToken string `mapstructure:"auth_token" yaml:"auth_token" comment:"Authentication token for the data availability layer service. Required if the DA service needs authentication."` GasPrice float64 `mapstructure:"gas_price" yaml:"gas_price" comment:"Gas price for data availability transactions. Use -1 for automatic gas price determination. Higher values may result in faster inclusion."` GasMultiplier float64 `mapstructure:"gas_multiplier" yaml:"gas_multiplier" comment:"Multiplier applied to gas price when retrying failed DA submissions. Values > 1 increase gas price on retries to improve chances of inclusion."` @@ -227,7 +227,7 @@ func AddGlobalFlags(cmd *cobra.Command, defaultHome string) { cmd.PersistentFlags().String(FlagRootDir, DefaultRootDirWithName(defaultHome), "Root directory for application data") } -// AddFlags adds Rollkit specific configuration options to cobra Command. +// AddFlags adds Evolve specific configuration options to cobra Command. func AddFlags(cmd *cobra.Command) { def := DefaultConfig diff --git a/pkg/config/defaults.go b/pkg/config/defaults.go index c5333e18f3..ce05442ffd 100644 --- a/pkg/config/defaults.go +++ b/pkg/config/defaults.go @@ -7,17 +7,17 @@ import ( ) const ( - // ConfigFileName is the base name of the rollkit configuration file without extension. + // ConfigFileName is the base name of the evolve configuration file without extension. ConfigFileName = "evnode" // ConfigExtension is the file extension for the configuration file without the leading dot. ConfigExtension = "yaml" - // ConfigPath is the filename for the rollkit configuration file. + // ConfigPath is the filename for the evolve configuration file. ConfigName = ConfigFileName + "." + ConfigExtension // AppConfigDir is the directory name for the app configuration. AppConfigDir = "config" ) -// DefaultRootDir returns the default root directory for rollkit +// DefaultRootDir returns the default root directory for evolve var DefaultRootDir = DefaultRootDirWithName(ConfigFileName) // DefaultRootDirWithName returns the default root directory for an application, @@ -39,7 +39,7 @@ func DefaultRootDirWithName(appName string) string { var DefaultConfig = Config{ RootDir: DefaultRootDir, DBPath: "data", - ChainID: "rollkit-test", + ChainID: "evolve-test", P2P: P2PConfig{ ListenAddress: "/ip4/0.0.0.0/tcp/7676", Peers: "", diff --git a/pkg/config/yaml.go b/pkg/config/yaml.go index c36148b797..e2d55e6b47 100644 --- a/pkg/config/yaml.go +++ b/pkg/config/yaml.go @@ -28,7 +28,7 @@ func (d *DurationWrapper) UnmarshalText(text []byte) error { return err } -// ErrReadYaml is the error returned when reading the rollkit.yaml file fails. +// ErrReadYaml is the error returned when reading the evolve.yaml file fails. var ErrReadYaml = fmt.Errorf("reading %s", ConfigName) // SaveAsYaml saves the current configuration to a YAML file. diff --git a/pkg/genesis/genesis.go b/pkg/genesis/genesis.go index e8481ab97e..521e39c67e 100644 --- a/pkg/genesis/genesis.go +++ b/pkg/genesis/genesis.go @@ -6,7 +6,7 @@ import ( ) // Genesis represents the genesis state of the blockchain. -// This genesis struct only contains the fields required by rollkit. +// This genesis struct only contains the fields required by evolve. // The app state or other fields are not included here. type Genesis struct { ChainID string `json:"chain_id"` diff --git a/pkg/p2p/README.md b/pkg/p2p/README.md index c6d2269be7..266623f5b8 100644 --- a/pkg/p2p/README.md +++ b/pkg/p2p/README.md @@ -1,6 +1,6 @@ # P2P Package -This document provides an overview of the P2P (peer-to-peer) networking system used in Rollkit. The P2P package leverages [go-libp2p](https://github.com/libp2p/go-libp2p) stack for establishing peer connections, gossiping transactions, and synchronizing headers and blocks across the network. +This document provides an overview of the P2P (peer-to-peer) networking system used in Evolve. The P2P package leverages [go-libp2p](https://github.com/libp2p/go-libp2p) stack for establishing peer connections, gossiping transactions, and synchronizing headers and blocks across the network. ## Overview @@ -15,7 +15,7 @@ Every node (both full and light) runs a P2P client for participating in the P2P ```mermaid graph TB - subgraph "Rollkit Node" + subgraph "Evolve Node" P2PClient["P2P Client"] TxValidator["Transaction Validator"] Mempool["Mempool"] @@ -214,7 +214,7 @@ ds := datastore.NewMapDatastore() logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)) // Create metrics -metrics := p2p.PrometheusMetrics("rollkit") +metrics := p2p.PrometheusMetrics("evolve") // Create client client, err := p2p.NewClient(conf, "mychain-1", ds, logger, metrics) diff --git a/pkg/rpc/README.md b/pkg/rpc/README.md index 81ccc6f645..9700f84da3 100644 --- a/pkg/rpc/README.md +++ b/pkg/rpc/README.md @@ -1,14 +1,14 @@ -# Rollkit RPC +# Evolve RPC -This package provides a Remote Procedure Call (RPC) interface for the Rollkit store package, implementing ADR-017. +This package provides a Remote Procedure Call (RPC) interface for the Evolve store package, implementing ADR-017. ## Overview -The RPC implementation uses [Connect-Go](https://connectrpc.com/docs/go/getting-started/) to create a modern, lightweight RPC layer that supports both gRPC and HTTP/1.1 protocols. This allows clients to interact with a Rollkit node's store remotely. +The RPC implementation uses [Connect-Go](https://connectrpc.com/docs/go/getting-started/) to create a modern, lightweight RPC layer that supports both gRPC and HTTP/1.1 protocols. This allows clients to interact with a Evolve node's store remotely. ## Directory Structure -```tree +```txt pkg/rpc/ ├── client/ # Client implementation │ └── client.go @@ -87,4 +87,4 @@ The RPC service provides the following methods: ## Protocol Buffers -The service is defined in `proto/rollkit/v1/rpc.proto`. The protocol buffer definitions are compiled using the standard Rollkit build process. +The service is defined in `proto/evolve/v1/rpc.proto`. The protocol buffer definitions are compiled using the standard evolve build process. diff --git a/pkg/rpc/server/server.go b/pkg/rpc/server/server.go index 0864ee5085..ca4b128e29 100644 --- a/pkg/rpc/server/server.go +++ b/pkg/rpc/server/server.go @@ -95,22 +95,22 @@ func (s *StoreServer) GetBlock( } // Fetch and set DA heights - rollkitBlockHeight := header.Height() - if rollkitBlockHeight > 0 { // DA heights are not stored for genesis/height 0 in the current impl - headerDAHeightKey := fmt.Sprintf("%s/%d/h", store.RollkitHeightToDAHeightKey, rollkitBlockHeight) + blockHeight := header.Height() + if blockHeight > 0 { // DA heights are not stored for genesis/height 0 in the current impl + headerDAHeightKey := fmt.Sprintf("%s/%d/h", store.HeightToDAHeightKey, blockHeight) headerDAHeightBytes, err := s.store.GetMetadata(ctx, headerDAHeightKey) if err == nil && len(headerDAHeightBytes) == 8 { resp.HeaderDaHeight = binary.LittleEndian.Uint64(headerDAHeightBytes) } else if err != nil && !errors.Is(err, ds.ErrNotFound) { - s.logger.Error().Uint64("height", rollkitBlockHeight).Err(err).Msg("Error fetching header DA height for block") + s.logger.Error().Uint64("height", blockHeight).Err(err).Msg("Error fetching header DA height for block") } - dataDAHeightKey := fmt.Sprintf("%s/%d/d", store.RollkitHeightToDAHeightKey, rollkitBlockHeight) + dataDAHeightKey := fmt.Sprintf("%s/%d/d", store.HeightToDAHeightKey, blockHeight) dataDAHeightBytes, err := s.store.GetMetadata(ctx, dataDAHeightKey) if err == nil && len(dataDAHeightBytes) == 8 { resp.DataDaHeight = binary.LittleEndian.Uint64(dataDAHeightBytes) } else if err != nil && !errors.Is(err, ds.ErrNotFound) { - s.logger.Error().Uint64("height", rollkitBlockHeight).Err(err).Msg("Error fetching data DA height for block") + s.logger.Error().Uint64("height", blockHeight).Err(err).Msg("Error fetching data DA height for block") } } diff --git a/pkg/rpc/server/server_test.go b/pkg/rpc/server/server_test.go index 00c4b6d16c..0e5a4c2844 100644 --- a/pkg/rpc/server/server_test.go +++ b/pkg/rpc/server/server_test.go @@ -51,8 +51,8 @@ func TestGetBlock(t *testing.T) { t.Run("by height with DA heights", func(t *testing.T) { // Setup mock expectations mockStore.On("GetBlockData", mock.Anything, height).Return(header, data, nil).Once() - mockStore.On("GetMetadata", mock.Anything, fmt.Sprintf("%s/%d/h", store.RollkitHeightToDAHeightKey, height)).Return(headerDAHeightBytes, nil).Once() - mockStore.On("GetMetadata", mock.Anything, fmt.Sprintf("%s/%d/d", store.RollkitHeightToDAHeightKey, height)).Return(dataDAHeightBytes, nil).Once() + mockStore.On("GetMetadata", mock.Anything, fmt.Sprintf("%s/%d/h", store.HeightToDAHeightKey, height)).Return(headerDAHeightBytes, nil).Once() + mockStore.On("GetMetadata", mock.Anything, fmt.Sprintf("%s/%d/d", store.HeightToDAHeightKey, height)).Return(dataDAHeightBytes, nil).Once() req := connect.NewRequest(&pb.GetBlockRequest{ Identifier: &pb.GetBlockRequest_Height{ @@ -72,8 +72,8 @@ func TestGetBlock(t *testing.T) { // Test GetBlock with height - metadata not found t.Run("by height DA heights not found", func(t *testing.T) { mockStore.On("GetBlockData", mock.Anything, height).Return(header, data, nil).Once() - mockStore.On("GetMetadata", mock.Anything, fmt.Sprintf("%s/%d/h", store.RollkitHeightToDAHeightKey, height)).Return(nil, ds.ErrNotFound).Once() - mockStore.On("GetMetadata", mock.Anything, fmt.Sprintf("%s/%d/d", store.RollkitHeightToDAHeightKey, height)).Return(nil, ds.ErrNotFound).Once() + mockStore.On("GetMetadata", mock.Anything, fmt.Sprintf("%s/%d/h", store.HeightToDAHeightKey, height)).Return(nil, ds.ErrNotFound).Once() + mockStore.On("GetMetadata", mock.Anything, fmt.Sprintf("%s/%d/d", store.HeightToDAHeightKey, height)).Return(nil, ds.ErrNotFound).Once() req := connect.NewRequest(&pb.GetBlockRequest{ Identifier: &pb.GetBlockRequest_Height{ @@ -94,8 +94,8 @@ func TestGetBlock(t *testing.T) { // Important: The header returned by GetBlockByHash must also have its height set for DA height lookup headerForHash := &types.SignedHeader{Header: types.Header{BaseHeader: types.BaseHeader{Height: height}}} mockStore.On("GetBlockByHash", mock.Anything, hashBytes).Return(headerForHash, data, nil).Once() - mockStore.On("GetMetadata", mock.Anything, fmt.Sprintf("%s/%d/h", store.RollkitHeightToDAHeightKey, height)).Return(headerDAHeightBytes, nil).Once() - mockStore.On("GetMetadata", mock.Anything, fmt.Sprintf("%s/%d/d", store.RollkitHeightToDAHeightKey, height)).Return(dataDAHeightBytes, nil).Once() + mockStore.On("GetMetadata", mock.Anything, fmt.Sprintf("%s/%d/h", store.HeightToDAHeightKey, height)).Return(headerDAHeightBytes, nil).Once() + mockStore.On("GetMetadata", mock.Anything, fmt.Sprintf("%s/%d/d", store.HeightToDAHeightKey, height)).Return(dataDAHeightBytes, nil).Once() req := connect.NewRequest(&pb.GetBlockRequest{ Identifier: &pb.GetBlockRequest_Hash{ @@ -155,8 +155,8 @@ func TestGetBlock_Latest(t *testing.T) { // Expectation for GetBlockData with the latest height mockStore.On("GetBlockData", context.Background(), latestHeight).Return(header, data, nil).Once() // Expectation for DA height metadata - mockStore.On("GetMetadata", mock.Anything, fmt.Sprintf("%s/%d/h", store.RollkitHeightToDAHeightKey, latestHeight)).Return(headerDAHeightBytes, nil).Once() - mockStore.On("GetMetadata", mock.Anything, fmt.Sprintf("%s/%d/d", store.RollkitHeightToDAHeightKey, latestHeight)).Return(dataDAHeightBytes, nil).Once() + mockStore.On("GetMetadata", mock.Anything, fmt.Sprintf("%s/%d/h", store.HeightToDAHeightKey, latestHeight)).Return(headerDAHeightBytes, nil).Once() + mockStore.On("GetMetadata", mock.Anything, fmt.Sprintf("%s/%d/d", store.HeightToDAHeightKey, latestHeight)).Return(dataDAHeightBytes, nil).Once() req := connect.NewRequest(&pb.GetBlockRequest{ Identifier: &pb.GetBlockRequest_Height{ diff --git a/pkg/signer/file/file_signer_test.go b/pkg/signer/file/file_signer_test.go index 3d73c88cb2..f33a1f854a 100644 --- a/pkg/signer/file/file_signer_test.go +++ b/pkg/signer/file/file_signer_test.go @@ -173,7 +173,7 @@ func TestSign(t *testing.T) { require.NoError(t, err) // Sign a message - message := []byte("Hello, Rollkit!") + message := []byte("Hello, Evolve!") signature, err := signer.Sign(message) require.NoError(t, err) require.NotNil(t, signature) diff --git a/pkg/store/README.md b/pkg/store/README.md index 51db92c540..ad94523e09 100644 --- a/pkg/store/README.md +++ b/pkg/store/README.md @@ -1,6 +1,6 @@ -# Rollkit Storage System +# Evolve Storage System -The `store` package provides a persistent storage solution for Rollkit, designed to efficiently store and retrieve blockchain data such as blocks, signatures, state, and metadata. +The `store` package provides a persistent storage solution for Evolve, designed to efficiently store and retrieve blockchain data such as blocks, signatures, state, and metadata. ## Overview @@ -124,7 +124,7 @@ if err != nil { myStore := store.New(kvStore) // Persistent store -kvStore, err := store.NewDefaultKVStore("/path/to/root", "data", "rollkit-db") +kvStore, err := store.NewDefaultKVStore("/path/to/root", "data", "ev-db") if err != nil { // handle error } diff --git a/pkg/store/keys.go b/pkg/store/keys.go index fb1c6e7737..f2a8b06686 100644 --- a/pkg/store/keys.go +++ b/pkg/store/keys.go @@ -7,10 +7,10 @@ import ( ) const ( - // RollkitHeightToDAHeightKey is the key prefix used for persisting the mapping from a Rollkit height + // HeightToDAHeightKey is the key prefix used for persisting the mapping from a Evolve height // to the DA height where the block's header/data was included. - // Full keys are like: rhb//h and rhb//d - RollkitHeightToDAHeightKey = "rhb" + // Full keys are like: rhb//h and rhb//d + HeightToDAHeightKey = "rhb" // DAIncludedHeightKey is the key used for persisting the da included height in store. DAIncludedHeightKey = "d" diff --git a/pkg/store/types.go b/pkg/store/types.go index 5c2f3b3300..18f6b6e90c 100644 --- a/pkg/store/types.go +++ b/pkg/store/types.go @@ -38,7 +38,7 @@ type Store interface { // SetMetadata saves arbitrary value in the store. // - // This method enables rollkit to safely persist any information. + // This method enables evolve to safely persist any information. SetMetadata(ctx context.Context, key string, value []byte) error // GetMetadata returns values stored for given key with SetMetadata. diff --git a/pkg/sync/README.md b/pkg/sync/README.md index 300d57ee54..be8878b7b4 100644 --- a/pkg/sync/README.md +++ b/pkg/sync/README.md @@ -1,10 +1,10 @@ -# Rollkit Sync Service +# Evolve Sync Service -This document explains how the Rollkit Sync Service works, its dependencies, and its architecture. +This document explains how the Evolve Sync Service works, its dependencies, and its architecture. ## Overview -Rollkit's Sync Service is responsible for synchronizing block headers and data across nodes in the Rollkit network. It's a critical component that allows nodes to maintain a consistent view of the blockchain state. +Evolve's Sync Service is responsible for synchronizing block headers and data across nodes in the Evolve network. It's a critical component that allows nodes to maintain a consistent view of the blockchain state. The sync mechanism consists of two main components: diff --git a/scripts/README-EVM.md b/scripts/README-EVM.md index d37cccb042..2daaa1d4f5 100644 --- a/scripts/README-EVM.md +++ b/scripts/README-EVM.md @@ -1,6 +1,6 @@ # EVM Node Scripts -This directory contains Go scripts for running Rollkit EVM nodes. +This directory contains Go scripts for running Evolve EVM nodes. ## run-evm-nodes.go @@ -49,7 +49,7 @@ go build -tags run_evm -o run-evm-nodes scripts/run-evm-nodes.go - Sequencer EVM: ports 8545 (RPC), 8551 (Engine), 8546 (WS) - Full Node EVM: ports 8555 (RPC), 8561 (Engine), 8556 (WS) -3. **Rollkit Nodes**: +3. **Evolve Nodes**: - Initializes and starts the sequencer node: - RPC: @@ -66,7 +66,7 @@ go build -tags run_evm -o run-evm-nodes scripts/run-evm-nodes.go ### Architecture -```ascii +```txt ┌─────────────────┐ ┌─────────────────┐ │ Sequencer │ │ Full Node │ │ (Aggregator) │◄────┤ │ @@ -104,7 +104,7 @@ The script performs comprehensive cleanup on exit: - 7676-7677 (P2P) - 8545, 8551, 8546 (Sequencer EVM) - 8555, 8561, 8556 (Full Node EVM) - - 36657, 46657 (Rollkit RPC) + - 36657, 46657 (Evolve RPC) 2. **Docker issues**: Make sure Docker daemon is running and you have permissions @@ -114,7 +114,7 @@ The script performs comprehensive cleanup on exit: ### Development -The script follows Rollkit's patterns: +The script follows Evolve's patterns: - Uses build tags for conditional compilation - Implements comprehensive process management diff --git a/sequencers/based/README.md b/sequencers/based/README.md index ab76ec2170..3a447f583b 100644 --- a/sequencers/based/README.md +++ b/sequencers/based/README.md @@ -8,7 +8,7 @@ This implementation supports EVM execution via `go-execution-evm` and allows con ## 📦 Features -- Modular Rollkit node launcher +- Modular Evolve node launcher - Supports **based sequencing** via Celestia or dummy DA - Integrated with EVM execution (reth + geth compatible) - Configurable DA layers (chain and based) diff --git a/sequencers/single/README.md b/sequencers/single/README.md index 3fd75ccd66..2b6184c3c4 100644 --- a/sequencers/single/README.md +++ b/sequencers/single/README.md @@ -1,6 +1,6 @@ # Single Sequencer -The single sequencer is a component of the Rollkit framework that handles transaction ordering and batch submission to a Data Availability (DA) layer. It provides a reliable way to sequence transactions for applications via a designed node called the sequencer. +The single sequencer is a component of the Evolve framework that handles transaction ordering and batch submission to a Data Availability (DA) layer. It provides a reliable way to sequence transactions for applications via a designed node called the sequencer. ## Overview diff --git a/test/docker-e2e/base_test.go b/test/docker-e2e/base_test.go index ae69270e19..771ca1f597 100644 --- a/test/docker-e2e/base_test.go +++ b/test/docker-e2e/base_test.go @@ -43,14 +43,14 @@ func (s *DockerTestSuite) TestBasicDockerE2E() { s.FundWallet(ctx, daWallet, 100_000_000_00) }) - s.T().Run("start rollkit chain node", func(t *testing.T) { + s.T().Run("start evolve chain node", func(t *testing.T) { s.StartRollkitNode(ctx, bridgeNode, s.rollkitChain.GetNodes()[0]) }) - s.T().Run("submit a transaction to the rollkit chain", func(t *testing.T) { + s.T().Run("submit a transaction to the evolve chain", func(t *testing.T) { rollkitNode := s.rollkitChain.GetNodes()[0] -// The http port resolvable by the test runner. + // The http port resolvable by the test runner. httpPort := rollkitNode.GetHostHTTPPort() client, err := NewClient("localhost", httpPort) diff --git a/test/e2e/evm_full_node_e2e_test.go b/test/e2e/evm_full_node_e2e_test.go index b93810dc26..e9477c307b 100644 --- a/test/e2e/evm_full_node_e2e_test.go +++ b/test/e2e/evm_full_node_e2e_test.go @@ -1,7 +1,7 @@ //go:build evm // +build evm -// Package e2e contains end-to-end tests for Rollkit's EVM integration. +// Package e2e contains end-to-end tests for Evolve's EVM integration. // // This file specifically tests the EVM full node functionality including: // - Full node synchronization via P2P with sequencer @@ -291,7 +291,7 @@ func setupSequencerWithFullNode(t *testing.T, sut *SystemUnderTest, sequencerHom // - Ensures EVM state consistency between sequencer and full node on the Reth side // // This test demonstrates that full nodes can sync with sequencers in real-time, -// validates the P2P block propagation mechanism in Rollkit, ensures that +// validates the P2P block propagation mechanism in Evolve, ensures that // the underlying EVM execution state remains consistent across all nodes, and // verifies that DA (Data Availability) inclusion processes blocks within expected // timeframes after allowing sufficient time for DA layer synchronization. @@ -474,7 +474,7 @@ func TestEvmSequencerWithFullNodeE2E(t *testing.T) { t.Logf(" • DA (Data Availability) inclusion processing within expected timeframes") t.Logf(" • EVM execution state consistency") t.Logf("") - t.Logf(" 🏆 All validation criteria met - distributed rollkit network is functioning correctly!") + t.Logf(" 🏆 All validation criteria met - distributed evolve network is functioning correctly!") } // TestEvmFullNodeBlockPropagationE2E tests that blocks produced by the aggregator @@ -1009,7 +1009,7 @@ func restartSequencerAndFullNode(t *testing.T, sut *SystemUnderTest, sequencerHo // - Comprehensive state synchronization validation between nodes // - Tests lazy mode behavior during initial setup and after restart // -// This test demonstrates that the distributed rollkit network maintains +// This test demonstrates that the distributed evolve network maintains // consistency and continues to function correctly even when all nodes // are restarted simultaneously, including mode changes. func TestEvmSequencerFullNodeRestartE2E(t *testing.T) { diff --git a/test/e2e/evm_sequencer_e2e_test.go b/test/e2e/evm_sequencer_e2e_test.go index 244c36b465..578872ee8c 100644 --- a/test/e2e/evm_sequencer_e2e_test.go +++ b/test/e2e/evm_sequencer_e2e_test.go @@ -1,7 +1,7 @@ //go:build evm // +build evm -// Package e2e contains end-to-end tests for Rollkit's EVM integration. +// Package e2e contains end-to-end tests for Evolve's EVM integration. // // This file specifically tests the EVM sequencer (aggregator) functionality including: // - Basic sequencer operation and transaction processing diff --git a/types/data.go b/types/data.go index b83751897d..ebecac30fb 100644 --- a/types/data.go +++ b/types/data.go @@ -29,7 +29,7 @@ type Metadata struct { LastDataHash Hash } -// Data defines Rollkit block data. +// Data defines Evolve block data. type Data struct { *Metadata Txs Txs diff --git a/types/header.go b/types/header.go index 5a2e9ff710..845cfc649f 100644 --- a/types/header.go +++ b/types/header.go @@ -47,7 +47,7 @@ type BaseHeader struct { ChainID string } -// Header defines the structure of Rollkit block header. +// Header defines the structure of Evolve block header. type Header struct { BaseHeader // Block and App version diff --git a/types/state.go b/types/state.go index bbb0421821..9d6e891a25 100644 --- a/types/state.go +++ b/types/state.go @@ -28,7 +28,7 @@ type State struct { LastBlockHeight uint64 LastBlockTime time.Time - // DAHeight identifies DA block containing the latest applied Rollkit block. + // DAHeight identifies DA block containing the latest applied Evolve block. DAHeight uint64 // Merkle root of the results from executing prev block