From c91e68db272a0df87b5bc3f467181ae447840fc0 Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Wed, 3 Dec 2025 14:23:51 +0100 Subject: [PATCH 1/6] doc updates --- .../src/architecture/execution-client.md | 29 ++++++----- .../src/architecture/index.md | 6 +-- .../src/local-devnet/command-line.md | 48 ++++++++++++++----- .../src/local-devnet/interactions.md | 16 +++++-- .../src/local-devnet/membership-changes.md | 11 +++-- .../src/local-devnet/monitoring.md | 20 +++++--- .../src/local-devnet/setup.md | 11 +++-- 7 files changed, 92 insertions(+), 49 deletions(-) diff --git a/docs/operational-docs/src/architecture/execution-client.md b/docs/operational-docs/src/architecture/execution-client.md index 6cac9cef..c552f8e6 100644 --- a/docs/operational-docs/src/architecture/execution-client.md +++ b/docs/operational-docs/src/architecture/execution-client.md @@ -3,9 +3,9 @@ Emerald integrates with Ethereum execution clients through [Engine API](https://github.com/ethereum/execution-apis/tree/main/src/engine), allowing it to plug into a mature execution ecosystem. Currently, Emerald integrates with [Reth](https://github.com/paradigmxyz/reth) and the roadmap includes support for additional clients. -## Key Properties +## Key Properties -**EVM Compatibility.** Users can run existing Ethereum smart contracts on Emerald without modification. +**EVM Compatibility.** Users can run existing Ethereum smart contracts on Emerald without modification. Consequently, they can leverage established standards such as ERC-20, ERC-721, and ERC-4626. **Rich Ecosystem Support.** Users get immediate access to wallets, block explorers, indexers, and developer frameworks. @@ -14,31 +14,31 @@ Emerald provides native compatibility with DeFi protocols, bridges, token standa **Continuous Performance Improvements.** Emerald benefits from ongoing optimizations and research from active Ethereum client development. Users remain aligned with performance and scalability upgrades adopted by the Ethereum ecosystem. -**Reduced development overhead.** Emerald networks do not need to build or maintain a custom execution layer, resulting in faster time-to-market with lower operational burden. +**Reduced development overhead.** Emerald networks do not need to build or maintain a custom execution layer, resulting in faster time-to-market with lower operational burden. -## Reth Integration +## Reth Integration In Emerald, it is the responsibility of the execution client to build and validate blocks as consensus has no application specific knowledge on what a block contains. -Emerald integrates with the execution client via Engine API. +Emerald integrates with the execution client via Engine API. In the context of Engine API, Emerald is the consensus layer that acts as a client issuing RPC requests to the execution client, which serves as the RPC server. The core methods are: - `exchangeCapabilities` Allows the consensus and execution clients to exchange and negotiate supported Engine API capabilities. It ensures both sides understand each other’s feature set (e.g., versioned payload types, optional fields), enabling forward compatibility and coordinated upgrades across client releases. -- `forkchoiceUpdated` Updates the execution client with the Emerald's latest finalized block. +- `forkchoiceUpdated` Updates the execution client with the Emerald's latest finalized block. If `payloadAttributes` are provided, it also instructs the execution client to begin building a new block and returns a `payloadId` for later retrieval. -- `getPayload` Returns the execution payload associated with a previously issued `payloadId`. +- `getPayload` Returns the execution payload associated with a previously issued `payloadId`. It finalizes the block under construction and hands it to Emerald so it can be proposed for inclusion on-chain. -- `newPayload` Delivers a newly built (i.e., proposed) execution payload from Emerald to the execution client for validation. +- `newPayload` Delivers a newly built (i.e., proposed) execution payload from Emerald to the execution client for validation. It verifies the block’s correctness and, if valid, incorporates it into the local chain state. For a detail description of these methods and how they work, please refer to the [Engine API visual guide](https://hackmd.io/@danielrachi/engine_api). Emerald is calling the Engine API RPC methods when handling events emitted by the [Malachite consensus engine](consensus.md): -- `AppMsg::ConsensusReady` Emerald calls `exchangeCapabilities` to check compatibility with the execution client. - Then, it gets the genesis block from the execution client by calling the `eth_getBlockByNumber` Ethereum RPC. +- `AppMsg::ConsensusReady` Emerald calls `exchangeCapabilities` to check compatibility with the execution client. + Then, it gets the genesis block from the execution client by calling the `eth_getBlockByNumber` Ethereum RPC. Note that when restarting after a crash, Emerald retrieves the latest decided block from its local store and calls `forkchoiceUpdated` to update the head of the chain in the execution client. - `AppMsg::StartedRound` Emerald starts the next height / round of consensus by retrieving pending proposal data and validating it against the execution client via a `newPayload` call. @@ -49,12 +49,11 @@ Emerald is calling the Engine API RPC methods when handling events emitted by th - `AppMsg::ReceivedProposalPart` When all the parts of a proposed blocked have been received, Emerald validates the block against the execution client by calling `newPayload`. - `AppMsg::Decided` Once consensus is reached, the block is validated again against the execution client (via a `newPayload` call). - This is necessary as the proposer has not called `newPayload` in `ReceiveProposalParts` - Then, a call to `forkchoiceUpdated` updates the head of the chain in the execution client. + This is necessary as the proposer has not called `newPayload` in `ReceiveProposalParts`. + Then, a call to `forkchoiceUpdated` updates the head of the chain in the execution client. As an optimization, Emerald avoid re-validation by caching blocks that have been validated already so that non-proposing nodes do not have to call `newPayload` twice. - `AppMsg::ProcessSyncedValue` When Emerald is syncing, it validates blocks received from other nodes by calling `newPayload` (as in `RecieveProposalParts`). -- `AppMsg::GetDecidedValue` When other Emerald nodes are syncing, they might ask for blocks that are no longer in the local store. - In that case, Emerald is calling `getPayload` to get the block from the execution client. - +- `AppMsg::GetDecidedValue` When other Emerald nodes are syncing, they might ask for blocks that are no longer in the local store. + In that case, Emerald is calling `getPayload` to get the block from the execution client. diff --git a/docs/operational-docs/src/architecture/index.md b/docs/operational-docs/src/architecture/index.md index 78ab72ec..ee059f3d 100644 --- a/docs/operational-docs/src/architecture/index.md +++ b/docs/operational-docs/src/architecture/index.md @@ -1,7 +1,7 @@ # Architecture -Emerald is a modular framework designed with simplicity at its core, enabling users to deploy reliable, easy to operate, high performance, EVM-compatible networks. -Its architecture is intentionally clean and composable, consisting of three key components. +Emerald is a modular framework designed with simplicity at its core, enabling users to deploy reliable, easy to operate, high performance, EVM-compatible networks. +Its architecture is intentionally clean and composable, consisting of three key components: - [Consensus Layer](consensus.md) - [Execution Layer](execution-client.md) @@ -9,4 +9,4 @@ Its architecture is intentionally clean and composable, consisting of three key
-
\ No newline at end of file + diff --git a/docs/operational-docs/src/local-devnet/command-line.md b/docs/operational-docs/src/local-devnet/command-line.md index a20bc1f7..febcf9e2 100644 --- a/docs/operational-docs/src/local-devnet/command-line.md +++ b/docs/operational-docs/src/local-devnet/command-line.md @@ -1,7 +1,7 @@ # CLI (Work in Progress) > [!NOTE] -> The Emerald CLI is a work in progress and should be considered experimental. +> The Emerald CLI is a work in progress and should be considered experimental. > Functionality may change, and users should expect potential instability or incomplete features. ## Start the Network @@ -14,6 +14,7 @@ Use the following command to start a local testnet: ```shell {{#include ../templates/help_templates/testnet/start.md}} ``` + For example, starting a testnet with four nodes results in the following output: @@ -133,6 +134,7 @@ Checking custom-reth installation... ✓ Reth Version: 1.9.2-dev emerald testnet stop - Stop all nodes emerald testnet destroy - Remove all testnet data ``` + ## Check Network Status @@ -145,9 +147,10 @@ Use the following command to check the network status: ```shell {{#include ../templates/help_templates/testnet/status.md}} ``` + -For example, checking the status after having started a four-node testnet should results in the following output: +For example, checking the status after having started a four-node testnet should result in the following output:
Output for emerald testnet status @@ -185,6 +188,7 @@ Summary: Emerald running: 4/4 Reth running: 4/4 ``` +
## Stop Node @@ -197,9 +201,10 @@ Use the following command to stop a single node: ``` {{#include ../templates/help_templates/testnet/stop-node.md}} ``` + -For example, running this command for Node `1` should results in the following output: +For example, running this command for Node `1` should result in the following output:
Output for emerald stop-node 1 @@ -210,9 +215,10 @@ For example, running this command for Node `1` should results in the following o ✅ Stopped 2 process(es) for node 1 ``` +
-And checking the network status should results in the following output: +And checking the network status should result in the following output:
Output for emerald status @@ -247,6 +253,7 @@ Summary: Emerald running: 3/4 Reth running: 3/4 ``` +
## Restart Node @@ -259,9 +266,10 @@ Use the following command to restart an existing node: ```shell {{#include ../templates/help_templates/testnet/start-node.md}} ``` + -For example, restarting the node that was previously stopped should results in the following output: +For example, restarting the node that was previously stopped should result in the following output:
Output for emerald start-node 1 @@ -298,9 +306,10 @@ Starting Reth node 1 on ports: Reth: $HOME/.emerald-devnet/1/logs/reth.log Emerald: $HOME/.emerald-devnet/1/logs/emerald.log ``` +
-And checking the network status should results in the following output: +And checking the network status should result in the following output:
Output for emerald status @@ -337,6 +346,7 @@ Summary: Emerald running: 4/4 Reth running: 4/4 ``` +
## Add Node @@ -349,9 +359,10 @@ Use the following command to add a new node to the network: ```shell {{#include ../templates/help_templates/testnet/add-node.md}} ``` + -Running this command should results in the following output: +Running this command should result in the following output:
Output for emerald add-node @@ -407,9 +418,10 @@ Starting Reth node 4 on ports: Reth: $HOME/.emerald-devnet/4/logs/reth.log Emerald: $HOME/.emerald-devnet/4/logs/emerald.log ``` +
-And checking the network status should results in the following output: +And checking the network status should result in the following output:
Output for emerald status @@ -452,6 +464,7 @@ Summary: Emerald running: 5/5 Reth running: 5/5 ``` +
## Set Node as Validator @@ -485,6 +498,7 @@ Validator #4: Pubkey: 049cdba83f09fd9f66cf5b45ce3db1866c85ce0041f0dcb3d64070196fc38690acc00c0dafa3289404b5615986e467720cf43ab970cc14c4f1f1a07774a992b3e0 Validator address: 0xe95eaa9dcd4f9e3b4eec820355c03b4f4499ab87 ``` + To add the new node as a validator, we first need to get its public key. @@ -494,9 +508,11 @@ To add the new node as a validator, we first need to get its public key. ``` 0x670252bba7f17bfa44ed4148aee562108a57f49e90017f940d80bd4a34e367710c192ed04ad87a71f6c3cff5d48b1baab8f423c01f534a01dee18b151b25a0f7 ``` + Once we have the public key, we can add the new node to the validator set using the following command: + ```shell emerald-utils poa -r http://127.0.0.1:8645 add-validator \ --validator-pubkey 0x670252bba7f17bfa44ed4148aee562108a57f49e90017f940d80bd4a34e367710c192ed04ad87a71f6c3cff5d48b1baab8f423c01f534a01dee18b151b25a0f7 \ @@ -506,7 +522,7 @@ emerald-utils poa -r http://127.0.0.1:8645 add-validator \
Output for -emerald-utils poa -r http://127.0.0.1:8645 add-validator +emerald-utils poa -r http://127.0.0.1:8645 add-validator ``` @@ -516,9 +532,10 @@ Transaction sent: 0xe1796369404585429fa24300d8f1f5433c8e5b477c992f1bd23e39d6c7de Transaction confirmed in block: Some(466) Gas used: 153301 ``` +
-And listing the validators should results in the following output: +And listing the validators should result in the following output:
Output for emerald-utils poa -r http://127.0.0.1:8645 list @@ -553,6 +570,7 @@ Validator #5: Pubkey: 04670252bba7f17bfa44ed4148aee562108a57f49e90017f940d80bd4a34e367710c192ed04ad87a71f6c3cff5d48b1baab8f423c01f534a01dee18b151b25a0f7 Validator address: 0x42dccf7844765f8205edbe4364d69d955fd1330a ``` +
For more details on interacting with the PoA Module, see [Managing Validators](./membership-changes.md) section. @@ -567,9 +585,10 @@ Use the following command to stop the local testnet: ```shell {{#include ../templates/help_templates/testnet/stop.md}} ``` + -Running this command should results in the following output: +Running this command should result in the following output:
Output for emerald testnet stop @@ -595,6 +614,7 @@ Stopping node 2... ✅ Stopped 10/10 processes ``` +
## Clean the Network @@ -607,9 +627,10 @@ Use the following command to remove all testnet data: ```shell {{#include ../templates/help_templates/testnet/destroy.md}} ``` + -Running this command should results in the following output: +Running this command should result in the following output:
Output for emerald testnet destroy @@ -624,4 +645,5 @@ Running this command should results in the following output: 🗑️ Removing testnet data... ✅ Testnet data removed successfully ``` -
\ No newline at end of file + + diff --git a/docs/operational-docs/src/local-devnet/interactions.md b/docs/operational-docs/src/local-devnet/interactions.md index a5192d32..d0cc4b48 100644 --- a/docs/operational-docs/src/local-devnet/interactions.md +++ b/docs/operational-docs/src/local-devnet/interactions.md @@ -5,6 +5,7 @@ Once your local Emerald testnet is running, you can interact with it like any Et ## Using `curl` (JSON-RPC) **Get current block number:** + ```bash curl -X POST http://127.0.0.1:8645 \ -H "Content-Type: application/json" \ @@ -12,13 +13,15 @@ curl -X POST http://127.0.0.1:8645 \ ``` **Get account balance:** + ```bash curl -X POST http://127.0.0.1:8645 \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","method":"eth_getBalance","params":["0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266","latest"],"id":1}' ``` -**Send a transaction:** +**Send a transaction:** (requires the "from" address private key in the Ethereum client) + ```bash curl -X POST http://127.0.0.1:8645 \ -H "Content-Type: application/json" \ @@ -40,16 +43,19 @@ curl -X POST http://127.0.0.1:8645 \ **Prerequisite:** [Foundry](https://getfoundry.sh/introduction/installation/) **Get block number:** + ```bash cast block-number --rpc-url http://127.0.0.1:8645 ``` **Check balance:** + ```bash cast balance 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 --rpc-url http://127.0.0.1:8645 ``` **Send ETH:** + ```bash cast send 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 \ --value 1ether \ @@ -62,8 +68,9 @@ cast send 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 \ Configure your Web3 library to connect to `http://127.0.0.1:8645`: **ethers.js (JavaScript):** + ```javascript -const { ethers } = require('ethers'); +import { ethers } from 'ethers'; const provider = new ethers.JsonRpcProvider('http://127.0.0.1:8645'); const wallet = new ethers.Wallet('0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80', provider); @@ -77,6 +84,7 @@ await tx.wait(); ``` **web3.py (Python):** + ```python from web3 import Web3 @@ -108,5 +116,5 @@ tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction) 5. Import one of the test accounts using its private key > [!WARNING] -> Only use test private keys with local networks. -> _**Never import test keys into wallets used for real funds.**_ \ No newline at end of file +> Only use test private keys with local networks. +> _**Never import test keys into wallets used for real funds.**_ diff --git a/docs/operational-docs/src/local-devnet/membership-changes.md b/docs/operational-docs/src/local-devnet/membership-changes.md index 047e69a8..f305d925 100644 --- a/docs/operational-docs/src/local-devnet/membership-changes.md +++ b/docs/operational-docs/src/local-devnet/membership-changes.md @@ -10,7 +10,7 @@ Emerald uses a Proof of Authority (PoA) smart contract (`ValidatorManager`) to m - Each validator's voting power - Who can modify the validator set (the contract owner) -Emerald's PoA tooling provides support for the following use cases. +Emerald's PoA tooling provides support for the following use cases. - **Testing validator changes.** Simulate adding/removing validators in a running network - **Testing voting power.** Experiment with different power distributions @@ -30,11 +30,13 @@ The local testnet uses a well-known test mnemonic for pre-funded accounts. **Mnemonic**: `test test test test test test test test test test test junk` **PoA Contract Owner (Account #0)**: + - **Private Key**: `0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80` - **Address**: `0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266` - **Role**: Has authority to add/remove/update validators **Validator Keys**: + - Located at `nodes/{0,1,2,3}/config/priv_validator_key.json` - These are separate from the Ethereum accounts - Used for consensus signing, not transactions @@ -72,6 +74,7 @@ To add a node to the validator set, you need the node's public key. There are tw - Use one of the existing validators after [removing](#remove-a-validator) it from the validator set. - Add a new node using the following command: + ```bash # replace ID with a specific node ID (e.g., 4) cargo run --bin emerald -- init --home nodes/{ID} @@ -111,7 +114,7 @@ To remove a validator from the active set: ```bash cargo run --bin emerald-utils poa -r http://127.0.0.1:8645 remove-validator \ - --validator-pubkey 0x04681eaaa34e491e6c8335abc9ea92b024ef52eb91442ca3b84598c79a79f31b75... \ + --validator-identifier 0x04681eaaa34e491e6c8335abc9ea92b024ef52eb91442ca3b84598c79a79f31b75... \ --owner-private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 ``` @@ -121,7 +124,7 @@ To change a validator's voting weight: ```bash cargo run --bin emerald-utils poa -r http://127.0.0.1:8645 update-validator \ - --validator-pubkey 0x04681eaaa34e491e6c8335abc9ea92b024ef52eb91442ca3b84598c79a79f31b75... \ + --validator-identifier 0x04681eaaa34e491e6c8335abc9ea92b024ef52eb91442ca3b84598c79a79f31b75... \ --power 200 \ --owner-private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 -``` \ No newline at end of file +``` diff --git a/docs/operational-docs/src/local-devnet/monitoring.md b/docs/operational-docs/src/local-devnet/monitoring.md index e5a50415..c1f7d91e 100644 --- a/docs/operational-docs/src/local-devnet/monitoring.md +++ b/docs/operational-docs/src/local-devnet/monitoring.md @@ -4,15 +4,17 @@ The `make testnet-start` command automatically starts monitoring services to hel ## Grafana - Metrics Visualization -**URL**: http://localhost:4000 +**URL**: Grafana provides visual dashboards for monitoring validator and network metrics. **Default credentials:** + - Username: `admin` - Password: `admin` (you'll be prompted to change this on first login, but you can skip it for local testing) **What to monitor:** + - **Block production rate**: Are validators producing blocks consistently? - **Consensus metrics**: Round times, vote counts, proposal statistics - **Node health**: CPU, memory, disk usage @@ -22,34 +24,38 @@ Grafana provides visual dashboards for monitoring validator and network metrics. ## Prometheus - Raw Metrics -**URL**: http://localhost:9090 +**URL**: Prometheus collects time-series metrics from all nodes. Use the query interface to explore raw metrics data. **Useful queries:** + - `emerald_consensus_height` - Current consensus height per node - `emerald_consensus_round` - Current consensus round - `emerald_mempool_size` - Number of transactions in mempool - `process_cpu_seconds_total` - CPU usage per process **When to use Prometheus:** + - Creating custom queries - Debugging specific metric issues - Exporting data for analysis ## Otterscan - Block Explorer -**URL**: http://localhost:80 +**URL**: Otterscan is a lightweight block explorer for inspecting blocks, transactions, and accounts. **Features:** + - View recent blocks and transactions - Search by address, transaction hash, or block number - Inspect contract interactions - View account balances and transaction history **Use cases:** + - Verify transactions were included in blocks - Debug smart contract interactions - Inspect validator activity @@ -61,13 +67,14 @@ View consensus logs for each validator: ```bash # View logs from validator 0 -tail -f nodes/0/emerald.log +tail -f nodes/0/logs/node.log # View logs from all validators simultaneously -tail -f nodes/{0,1,2,3}/emerald.log +tail -f nodes/{0,1,2,3}/logs/node.log ``` **What to look for:** + - Block proposals and commits - Consensus round progression - Validator voting activity @@ -86,7 +93,8 @@ docker compose logs -f reth0 reth1 reth2 reth3 ``` **What to look for:** + - Block execution confirmations - Transaction processing - Peer connection status -- Engine API communication with Emerald \ No newline at end of file +- Engine API communication with Emerald diff --git a/docs/operational-docs/src/local-devnet/setup.md b/docs/operational-docs/src/local-devnet/setup.md index b95e1729..9e8726f3 100644 --- a/docs/operational-docs/src/local-devnet/setup.md +++ b/docs/operational-docs/src/local-devnet/setup.md @@ -10,12 +10,15 @@ Before starting, ensure you have: - Docker Compose (usually included with Docker Desktop) - Make (typically pre-installed on Linux/macOS; Windows users can use WSL) - Git (for cloning the repository) +- [Protobuf](https://protobuf.dev/installation) (to compile Emerald `.proto` files) **Verify installations:** + ```bash -rustc --version # Should show rustc 1.85+ +rustc --version # Should show rustc 1.88+ docker --version # Should show Docker 20.10+ -make --version # Should show GNU Make +make --version # Should show GNU Make 3.81+ +protoc --version # Should show libprotoc 33.1+ ``` ## Installation @@ -24,7 +27,7 @@ make --version # Should show GNU Make git clone https://github.com/informalsystems/emerald.git cd emerald make build -``` +``` > [!NOTE] -> For building in release mode, use `make release`. \ No newline at end of file +> For building in release mode, use `make release`. From e3872f6ae22f21cd4396e9f4902eb2916f31ce0f Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Wed, 3 Dec 2025 16:40:59 +0100 Subject: [PATCH 2/6] Revert mardown files linting in docs --- .../src/architecture/execution-client.md | 27 +++++++++--------- .../src/architecture/index.md | 2 +- .../src/local-devnet/command-line.md | 28 ++----------------- .../src/local-devnet/interactions.md | 6 ++-- .../src/local-devnet/membership-changes.md | 4 +-- .../src/local-devnet/monitoring.md | 2 +- .../src/local-devnet/setup.md | 5 ++-- 7 files changed, 25 insertions(+), 49 deletions(-) diff --git a/docs/operational-docs/src/architecture/execution-client.md b/docs/operational-docs/src/architecture/execution-client.md index c552f8e6..3b0768be 100644 --- a/docs/operational-docs/src/architecture/execution-client.md +++ b/docs/operational-docs/src/architecture/execution-client.md @@ -3,9 +3,9 @@ Emerald integrates with Ethereum execution clients through [Engine API](https://github.com/ethereum/execution-apis/tree/main/src/engine), allowing it to plug into a mature execution ecosystem. Currently, Emerald integrates with [Reth](https://github.com/paradigmxyz/reth) and the roadmap includes support for additional clients. -## Key Properties +## Key Properties -**EVM Compatibility.** Users can run existing Ethereum smart contracts on Emerald without modification. +**EVM Compatibility.** Users can run existing Ethereum smart contracts on Emerald without modification. Consequently, they can leverage established standards such as ERC-20, ERC-721, and ERC-4626. **Rich Ecosystem Support.** Users get immediate access to wallets, block explorers, indexers, and developer frameworks. @@ -14,31 +14,31 @@ Emerald provides native compatibility with DeFi protocols, bridges, token standa **Continuous Performance Improvements.** Emerald benefits from ongoing optimizations and research from active Ethereum client development. Users remain aligned with performance and scalability upgrades adopted by the Ethereum ecosystem. -**Reduced development overhead.** Emerald networks do not need to build or maintain a custom execution layer, resulting in faster time-to-market with lower operational burden. +**Reduced development overhead.** Emerald networks do not need to build or maintain a custom execution layer, resulting in faster time-to-market with lower operational burden. -## Reth Integration +## Reth Integration In Emerald, it is the responsibility of the execution client to build and validate blocks as consensus has no application specific knowledge on what a block contains. -Emerald integrates with the execution client via Engine API. +Emerald integrates with the execution client via Engine API. In the context of Engine API, Emerald is the consensus layer that acts as a client issuing RPC requests to the execution client, which serves as the RPC server. The core methods are: - `exchangeCapabilities` Allows the consensus and execution clients to exchange and negotiate supported Engine API capabilities. It ensures both sides understand each other’s feature set (e.g., versioned payload types, optional fields), enabling forward compatibility and coordinated upgrades across client releases. -- `forkchoiceUpdated` Updates the execution client with the Emerald's latest finalized block. +- `forkchoiceUpdated` Updates the execution client with the Emerald's latest finalized block. If `payloadAttributes` are provided, it also instructs the execution client to begin building a new block and returns a `payloadId` for later retrieval. -- `getPayload` Returns the execution payload associated with a previously issued `payloadId`. +- `getPayload` Returns the execution payload associated with a previously issued `payloadId`. It finalizes the block under construction and hands it to Emerald so it can be proposed for inclusion on-chain. -- `newPayload` Delivers a newly built (i.e., proposed) execution payload from Emerald to the execution client for validation. +- `newPayload` Delivers a newly built (i.e., proposed) execution payload from Emerald to the execution client for validation. It verifies the block’s correctness and, if valid, incorporates it into the local chain state. For a detail description of these methods and how they work, please refer to the [Engine API visual guide](https://hackmd.io/@danielrachi/engine_api). Emerald is calling the Engine API RPC methods when handling events emitted by the [Malachite consensus engine](consensus.md): -- `AppMsg::ConsensusReady` Emerald calls `exchangeCapabilities` to check compatibility with the execution client. - Then, it gets the genesis block from the execution client by calling the `eth_getBlockByNumber` Ethereum RPC. +- `AppMsg::ConsensusReady` Emerald calls `exchangeCapabilities` to check compatibility with the execution client. + Then, it gets the genesis block from the execution client by calling the `eth_getBlockByNumber` Ethereum RPC. Note that when restarting after a crash, Emerald retrieves the latest decided block from its local store and calls `forkchoiceUpdated` to update the head of the chain in the execution client. - `AppMsg::StartedRound` Emerald starts the next height / round of consensus by retrieving pending proposal data and validating it against the execution client via a `newPayload` call. @@ -48,12 +48,11 @@ Emerald is calling the Engine API RPC methods when handling events emitted by th - `AppMsg::ReceivedProposalPart` When all the parts of a proposed blocked have been received, Emerald validates the block against the execution client by calling `newPayload`. -- `AppMsg::Decided` Once consensus is reached, the block is validated again against the execution client (via a `newPayload` call). - This is necessary as the proposer has not called `newPayload` in `ReceiveProposalParts`. +- `AppMsg::Decided` Once consensus is reached, the block is validated again against the execution client (via a `newPayload` call).This is necessary as the proposer has not called `newPayload` in `ReceiveProposalParts`. Then, a call to `forkchoiceUpdated` updates the head of the chain in the execution client. As an optimization, Emerald avoid re-validation by caching blocks that have been validated already so that non-proposing nodes do not have to call `newPayload` twice. - `AppMsg::ProcessSyncedValue` When Emerald is syncing, it validates blocks received from other nodes by calling `newPayload` (as in `RecieveProposalParts`). -- `AppMsg::GetDecidedValue` When other Emerald nodes are syncing, they might ask for blocks that are no longer in the local store. - In that case, Emerald is calling `getPayload` to get the block from the execution client. +- `AppMsg::GetDecidedValue` When other Emerald nodes are syncing, they might ask for blocks that are no longer in the local store. + In that case, Emerald is calling `getPayload` to get the block from the execution client. diff --git a/docs/operational-docs/src/architecture/index.md b/docs/operational-docs/src/architecture/index.md index ee059f3d..c1f786a3 100644 --- a/docs/operational-docs/src/architecture/index.md +++ b/docs/operational-docs/src/architecture/index.md @@ -9,4 +9,4 @@ Its architecture is intentionally clean and composable, consisting of three key
-
+ \ No newline at end of file diff --git a/docs/operational-docs/src/local-devnet/command-line.md b/docs/operational-docs/src/local-devnet/command-line.md index febcf9e2..5a487115 100644 --- a/docs/operational-docs/src/local-devnet/command-line.md +++ b/docs/operational-docs/src/local-devnet/command-line.md @@ -1,7 +1,7 @@ # CLI (Work in Progress) > [!NOTE] -> The Emerald CLI is a work in progress and should be considered experimental. +> The Emerald CLI is a work in progress and should be considered experimental. > Functionality may change, and users should expect potential instability or incomplete features. ## Start the Network @@ -14,7 +14,6 @@ Use the following command to start a local testnet: ```shell {{#include ../templates/help_templates/testnet/start.md}} ``` - For example, starting a testnet with four nodes results in the following output: @@ -134,7 +133,6 @@ Checking custom-reth installation... ✓ Reth Version: 1.9.2-dev emerald testnet stop - Stop all nodes emerald testnet destroy - Remove all testnet data ``` - ## Check Network Status @@ -147,7 +145,6 @@ Use the following command to check the network status: ```shell {{#include ../templates/help_templates/testnet/status.md}} ``` - For example, checking the status after having started a four-node testnet should result in the following output: @@ -188,7 +185,6 @@ Summary: Emerald running: 4/4 Reth running: 4/4 ``` - ## Stop Node @@ -201,7 +197,6 @@ Use the following command to stop a single node: ``` {{#include ../templates/help_templates/testnet/stop-node.md}} ``` - For example, running this command for Node `1` should result in the following output: @@ -215,7 +210,6 @@ For example, running this command for Node `1` should result in the following ou ✅ Stopped 2 process(es) for node 1 ``` - And checking the network status should result in the following output: @@ -253,7 +247,6 @@ Summary: Emerald running: 3/4 Reth running: 3/4 ``` - ## Restart Node @@ -266,7 +259,6 @@ Use the following command to restart an existing node: ```shell {{#include ../templates/help_templates/testnet/start-node.md}} ``` - For example, restarting the node that was previously stopped should result in the following output: @@ -306,7 +298,6 @@ Starting Reth node 1 on ports: Reth: $HOME/.emerald-devnet/1/logs/reth.log Emerald: $HOME/.emerald-devnet/1/logs/emerald.log ``` - And checking the network status should result in the following output: @@ -346,7 +337,6 @@ Summary: Emerald running: 4/4 Reth running: 4/4 ``` - ## Add Node @@ -359,7 +349,6 @@ Use the following command to add a new node to the network: ```shell {{#include ../templates/help_templates/testnet/add-node.md}} ``` - Running this command should result in the following output: @@ -418,7 +407,6 @@ Starting Reth node 4 on ports: Reth: $HOME/.emerald-devnet/4/logs/reth.log Emerald: $HOME/.emerald-devnet/4/logs/emerald.log ``` - And checking the network status should result in the following output: @@ -464,7 +452,6 @@ Summary: Emerald running: 5/5 Reth running: 5/5 ``` - ## Set Node as Validator @@ -498,7 +485,6 @@ Validator #4: Pubkey: 049cdba83f09fd9f66cf5b45ce3db1866c85ce0041f0dcb3d64070196fc38690acc00c0dafa3289404b5615986e467720cf43ab970cc14c4f1f1a07774a992b3e0 Validator address: 0xe95eaa9dcd4f9e3b4eec820355c03b4f4499ab87 ``` - To add the new node as a validator, we first need to get its public key. @@ -508,11 +494,9 @@ To add the new node as a validator, we first need to get its public key. ``` 0x670252bba7f17bfa44ed4148aee562108a57f49e90017f940d80bd4a34e367710c192ed04ad87a71f6c3cff5d48b1baab8f423c01f534a01dee18b151b25a0f7 ``` - Once we have the public key, we can add the new node to the validator set using the following command: - ```shell emerald-utils poa -r http://127.0.0.1:8645 add-validator \ --validator-pubkey 0x670252bba7f17bfa44ed4148aee562108a57f49e90017f940d80bd4a34e367710c192ed04ad87a71f6c3cff5d48b1baab8f423c01f534a01dee18b151b25a0f7 \ @@ -522,7 +506,7 @@ emerald-utils poa -r http://127.0.0.1:8645 add-validator \
Output for -emerald-utils poa -r http://127.0.0.1:8645 add-validator +emerald-utils poa -r http://127.0.0.1:8645 add-validator ``` @@ -532,7 +516,6 @@ Transaction sent: 0xe1796369404585429fa24300d8f1f5433c8e5b477c992f1bd23e39d6c7de Transaction confirmed in block: Some(466) Gas used: 153301 ``` -
And listing the validators should result in the following output: @@ -570,7 +553,6 @@ Validator #5: Pubkey: 04670252bba7f17bfa44ed4148aee562108a57f49e90017f940d80bd4a34e367710c192ed04ad87a71f6c3cff5d48b1baab8f423c01f534a01dee18b151b25a0f7 Validator address: 0x42dccf7844765f8205edbe4364d69d955fd1330a ``` - For more details on interacting with the PoA Module, see [Managing Validators](./membership-changes.md) section. @@ -585,7 +567,6 @@ Use the following command to stop the local testnet: ```shell {{#include ../templates/help_templates/testnet/stop.md}} ``` - Running this command should result in the following output: @@ -614,7 +595,6 @@ Stopping node 2... ✅ Stopped 10/10 processes ``` - ## Clean the Network @@ -627,7 +607,6 @@ Use the following command to remove all testnet data: ```shell {{#include ../templates/help_templates/testnet/destroy.md}} ``` - Running this command should result in the following output: @@ -645,5 +624,4 @@ Running this command should result in the following output: 🗑️ Removing testnet data... ✅ Testnet data removed successfully ``` - - + \ No newline at end of file diff --git a/docs/operational-docs/src/local-devnet/interactions.md b/docs/operational-docs/src/local-devnet/interactions.md index d0cc4b48..6d79180a 100644 --- a/docs/operational-docs/src/local-devnet/interactions.md +++ b/docs/operational-docs/src/local-devnet/interactions.md @@ -20,7 +20,7 @@ curl -X POST http://127.0.0.1:8645 \ -d '{"jsonrpc":"2.0","method":"eth_getBalance","params":["0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266","latest"],"id":1}' ``` -**Send a transaction:** (requires the "from" address private key in the Ethereum client) +**Send a transaction:** ```bash curl -X POST http://127.0.0.1:8645 \ @@ -116,5 +116,5 @@ tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction) 5. Import one of the test accounts using its private key > [!WARNING] -> Only use test private keys with local networks. -> _**Never import test keys into wallets used for real funds.**_ +> Only use test private keys with local networks. +> _**Never import test keys into wallets used for real funds.**_ \ No newline at end of file diff --git a/docs/operational-docs/src/local-devnet/membership-changes.md b/docs/operational-docs/src/local-devnet/membership-changes.md index f305d925..00ad5deb 100644 --- a/docs/operational-docs/src/local-devnet/membership-changes.md +++ b/docs/operational-docs/src/local-devnet/membership-changes.md @@ -10,7 +10,7 @@ Emerald uses a Proof of Authority (PoA) smart contract (`ValidatorManager`) to m - Each validator's voting power - Who can modify the validator set (the contract owner) -Emerald's PoA tooling provides support for the following use cases. +Emerald's PoA tooling provides support for the following use cases. - **Testing validator changes.** Simulate adding/removing validators in a running network - **Testing voting power.** Experiment with different power distributions @@ -127,4 +127,4 @@ cargo run --bin emerald-utils poa -r http://127.0.0.1:8645 update-validator \ --validator-identifier 0x04681eaaa34e491e6c8335abc9ea92b024ef52eb91442ca3b84598c79a79f31b75... \ --power 200 \ --owner-private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 -``` +``` \ No newline at end of file diff --git a/docs/operational-docs/src/local-devnet/monitoring.md b/docs/operational-docs/src/local-devnet/monitoring.md index c1f7d91e..e355eba6 100644 --- a/docs/operational-docs/src/local-devnet/monitoring.md +++ b/docs/operational-docs/src/local-devnet/monitoring.md @@ -97,4 +97,4 @@ docker compose logs -f reth0 reth1 reth2 reth3 - Block execution confirmations - Transaction processing - Peer connection status -- Engine API communication with Emerald +- Engine API communication with Emerald \ No newline at end of file diff --git a/docs/operational-docs/src/local-devnet/setup.md b/docs/operational-docs/src/local-devnet/setup.md index 9e8726f3..b6188671 100644 --- a/docs/operational-docs/src/local-devnet/setup.md +++ b/docs/operational-docs/src/local-devnet/setup.md @@ -10,7 +10,6 @@ Before starting, ensure you have: - Docker Compose (usually included with Docker Desktop) - Make (typically pre-installed on Linux/macOS; Windows users can use WSL) - Git (for cloning the repository) -- [Protobuf](https://protobuf.dev/installation) (to compile Emerald `.proto` files) **Verify installations:** @@ -27,7 +26,7 @@ protoc --version # Should show libprotoc 33.1+ git clone https://github.com/informalsystems/emerald.git cd emerald make build -``` +``` > [!NOTE] -> For building in release mode, use `make release`. +> For building in release mode, use `make release`. \ No newline at end of file From d233c6fdf7b7785e90dbebc48de432c1b57fb6ca Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Wed, 3 Dec 2025 16:54:59 +0100 Subject: [PATCH 3/6] fix linting --- .../src/architecture/execution-client.md | 5 +++-- docs/operational-docs/src/architecture/index.md | 4 ++-- .../src/local-devnet/interactions.md | 8 -------- .../src/local-devnet/membership-changes.md | 3 --- .../src/local-devnet/monitoring.md | 14 +++----------- docs/operational-docs/src/local-devnet/setup.md | 1 - 6 files changed, 8 insertions(+), 27 deletions(-) diff --git a/docs/operational-docs/src/architecture/execution-client.md b/docs/operational-docs/src/architecture/execution-client.md index 3b0768be..18112710 100644 --- a/docs/operational-docs/src/architecture/execution-client.md +++ b/docs/operational-docs/src/architecture/execution-client.md @@ -48,8 +48,9 @@ Emerald is calling the Engine API RPC methods when handling events emitted by th - `AppMsg::ReceivedProposalPart` When all the parts of a proposed blocked have been received, Emerald validates the block against the execution client by calling `newPayload`. -- `AppMsg::Decided` Once consensus is reached, the block is validated again against the execution client (via a `newPayload` call).This is necessary as the proposer has not called `newPayload` in `ReceiveProposalParts`. - Then, a call to `forkchoiceUpdated` updates the head of the chain in the execution client. +- `AppMsg::Decided` Once consensus is reached, the block is validated again against the execution client (via a `newPayload` call). + This is necessary as the proposer has not called `newPayload` in `ReceiveProposalParts`. + Then, a call to `forkchoiceUpdated` updates the head of the chain in the execution client. As an optimization, Emerald avoid re-validation by caching blocks that have been validated already so that non-proposing nodes do not have to call `newPayload` twice. - `AppMsg::ProcessSyncedValue` When Emerald is syncing, it validates blocks received from other nodes by calling `newPayload` (as in `RecieveProposalParts`). diff --git a/docs/operational-docs/src/architecture/index.md b/docs/operational-docs/src/architecture/index.md index c1f786a3..bc85aaeb 100644 --- a/docs/operational-docs/src/architecture/index.md +++ b/docs/operational-docs/src/architecture/index.md @@ -1,7 +1,7 @@ # Architecture -Emerald is a modular framework designed with simplicity at its core, enabling users to deploy reliable, easy to operate, high performance, EVM-compatible networks. -Its architecture is intentionally clean and composable, consisting of three key components: +Emerald is a modular framework designed with simplicity at its core, enabling users to deploy reliable, easy to operate, high performance, EVM-compatible networks. +Its architecture is intentionally clean and composable, consisting of three key components: - [Consensus Layer](consensus.md) - [Execution Layer](execution-client.md) diff --git a/docs/operational-docs/src/local-devnet/interactions.md b/docs/operational-docs/src/local-devnet/interactions.md index 6d79180a..b3e78242 100644 --- a/docs/operational-docs/src/local-devnet/interactions.md +++ b/docs/operational-docs/src/local-devnet/interactions.md @@ -5,7 +5,6 @@ Once your local Emerald testnet is running, you can interact with it like any Et ## Using `curl` (JSON-RPC) **Get current block number:** - ```bash curl -X POST http://127.0.0.1:8645 \ -H "Content-Type: application/json" \ @@ -13,7 +12,6 @@ curl -X POST http://127.0.0.1:8645 \ ``` **Get account balance:** - ```bash curl -X POST http://127.0.0.1:8645 \ -H "Content-Type: application/json" \ @@ -21,7 +19,6 @@ curl -X POST http://127.0.0.1:8645 \ ``` **Send a transaction:** - ```bash curl -X POST http://127.0.0.1:8645 \ -H "Content-Type: application/json" \ @@ -43,19 +40,16 @@ curl -X POST http://127.0.0.1:8645 \ **Prerequisite:** [Foundry](https://getfoundry.sh/introduction/installation/) **Get block number:** - ```bash cast block-number --rpc-url http://127.0.0.1:8645 ``` **Check balance:** - ```bash cast balance 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 --rpc-url http://127.0.0.1:8645 ``` **Send ETH:** - ```bash cast send 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 \ --value 1ether \ @@ -68,7 +62,6 @@ cast send 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 \ Configure your Web3 library to connect to `http://127.0.0.1:8645`: **ethers.js (JavaScript):** - ```javascript import { ethers } from 'ethers'; @@ -84,7 +77,6 @@ await tx.wait(); ``` **web3.py (Python):** - ```python from web3 import Web3 diff --git a/docs/operational-docs/src/local-devnet/membership-changes.md b/docs/operational-docs/src/local-devnet/membership-changes.md index 00ad5deb..4b1c2e25 100644 --- a/docs/operational-docs/src/local-devnet/membership-changes.md +++ b/docs/operational-docs/src/local-devnet/membership-changes.md @@ -30,13 +30,11 @@ The local testnet uses a well-known test mnemonic for pre-funded accounts. **Mnemonic**: `test test test test test test test test test test test junk` **PoA Contract Owner (Account #0)**: - - **Private Key**: `0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80` - **Address**: `0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266` - **Role**: Has authority to add/remove/update validators **Validator Keys**: - - Located at `nodes/{0,1,2,3}/config/priv_validator_key.json` - These are separate from the Ethereum accounts - Used for consensus signing, not transactions @@ -74,7 +72,6 @@ To add a node to the validator set, you need the node's public key. There are tw - Use one of the existing validators after [removing](#remove-a-validator) it from the validator set. - Add a new node using the following command: - ```bash # replace ID with a specific node ID (e.g., 4) cargo run --bin emerald -- init --home nodes/{ID} diff --git a/docs/operational-docs/src/local-devnet/monitoring.md b/docs/operational-docs/src/local-devnet/monitoring.md index e355eba6..36e5888d 100644 --- a/docs/operational-docs/src/local-devnet/monitoring.md +++ b/docs/operational-docs/src/local-devnet/monitoring.md @@ -4,17 +4,15 @@ The `make testnet-start` command automatically starts monitoring services to hel ## Grafana - Metrics Visualization -**URL**: +**URL**: http://localhost:4000 Grafana provides visual dashboards for monitoring validator and network metrics. **Default credentials:** - - Username: `admin` - Password: `admin` (you'll be prompted to change this on first login, but you can skip it for local testing) **What to monitor:** - - **Block production rate**: Are validators producing blocks consistently? - **Consensus metrics**: Round times, vote counts, proposal statistics - **Node health**: CPU, memory, disk usage @@ -24,38 +22,34 @@ Grafana provides visual dashboards for monitoring validator and network metrics. ## Prometheus - Raw Metrics -**URL**: +**URL**: http://localhost:9090 Prometheus collects time-series metrics from all nodes. Use the query interface to explore raw metrics data. **Useful queries:** - - `emerald_consensus_height` - Current consensus height per node - `emerald_consensus_round` - Current consensus round - `emerald_mempool_size` - Number of transactions in mempool - `process_cpu_seconds_total` - CPU usage per process **When to use Prometheus:** - - Creating custom queries - Debugging specific metric issues - Exporting data for analysis ## Otterscan - Block Explorer -**URL**: +**URL**: http://localhost:80 Otterscan is a lightweight block explorer for inspecting blocks, transactions, and accounts. **Features:** - - View recent blocks and transactions - Search by address, transaction hash, or block number - Inspect contract interactions - View account balances and transaction history **Use cases:** - - Verify transactions were included in blocks - Debug smart contract interactions - Inspect validator activity @@ -74,7 +68,6 @@ tail -f nodes/{0,1,2,3}/logs/node.log ``` **What to look for:** - - Block proposals and commits - Consensus round progression - Validator voting activity @@ -93,7 +86,6 @@ docker compose logs -f reth0 reth1 reth2 reth3 ``` **What to look for:** - - Block execution confirmations - Transaction processing - Peer connection status diff --git a/docs/operational-docs/src/local-devnet/setup.md b/docs/operational-docs/src/local-devnet/setup.md index b6188671..5cfd9fd8 100644 --- a/docs/operational-docs/src/local-devnet/setup.md +++ b/docs/operational-docs/src/local-devnet/setup.md @@ -12,7 +12,6 @@ Before starting, ensure you have: - Git (for cloning the repository) **Verify installations:** - ```bash rustc --version # Should show rustc 1.88+ docker --version # Should show Docker 20.10+ From 408dea0dfe7dc23d7a564cc72e9e406baaabdc26 Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Wed, 3 Dec 2025 17:11:08 +0100 Subject: [PATCH 4/6] add Protobuf to setup preriquisite --- docs/operational-docs/src/local-devnet/setup.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/operational-docs/src/local-devnet/setup.md b/docs/operational-docs/src/local-devnet/setup.md index 5cfd9fd8..54c0c490 100644 --- a/docs/operational-docs/src/local-devnet/setup.md +++ b/docs/operational-docs/src/local-devnet/setup.md @@ -10,6 +10,7 @@ Before starting, ensure you have: - Docker Compose (usually included with Docker Desktop) - Make (typically pre-installed on Linux/macOS; Windows users can use WSL) - Git (for cloning the repository) +- [Protobuf](https://protobuf.dev/installation) (to compile Emerald `.proto` files) **Verify installations:** ```bash From 7c8ef6ac175e1ca4790fbf795efdb520ce1cf22a Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Wed, 3 Dec 2025 17:16:59 +0100 Subject: [PATCH 5/6] remove eth_sendTransaction example from docs --- .../src/local-devnet/interactions.md | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/docs/operational-docs/src/local-devnet/interactions.md b/docs/operational-docs/src/local-devnet/interactions.md index b3e78242..ba42e773 100644 --- a/docs/operational-docs/src/local-devnet/interactions.md +++ b/docs/operational-docs/src/local-devnet/interactions.md @@ -18,23 +18,6 @@ curl -X POST http://127.0.0.1:8645 \ -d '{"jsonrpc":"2.0","method":"eth_getBalance","params":["0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266","latest"],"id":1}' ``` -**Send a transaction:** -```bash -curl -X POST http://127.0.0.1:8645 \ - -H "Content-Type: application/json" \ - -d '{ - "jsonrpc":"2.0", - "method":"eth_sendTransaction", - "params":[{ - "from":"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", - "to":"0x70997970C51812dc3A010C7d01b50e0d17dc79C8", - "value":"0x1000000000000000000", - "gas":"0x5208" - }], - "id":1 - }' -``` - ## Using `cast` (Foundry) **Prerequisite:** [Foundry](https://getfoundry.sh/introduction/installation/) From f755d6c4a9c810f7defe284570c009a64fcb8cb4 Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Thu, 4 Dec 2025 08:28:37 +0100 Subject: [PATCH 6/6] fix typo --- docs/operational-docs/src/local-devnet/troubleshooting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/operational-docs/src/local-devnet/troubleshooting.md b/docs/operational-docs/src/local-devnet/troubleshooting.md index 1f2146ba..16578f0c 100644 --- a/docs/operational-docs/src/local-devnet/troubleshooting.md +++ b/docs/operational-docs/src/local-devnet/troubleshooting.md @@ -24,7 +24,7 @@ 4. Check emerald logs ```bash - tail -f nodes/0/emerald.log + tail -f nodes/0/logs/node.log ``` ## Validator Operations Fail