mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
docs(exex): include code for ExEx book from real files (#11545)
This commit is contained in:
12
.github/workflows/lint.yml
vendored
12
.github/workflows/lint.yml
vendored
@ -30,7 +30,12 @@ jobs:
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
cache-on-failure: true
|
||||
- run: cargo clippy --bin "${{ matrix.binary }}" --workspace --features "${{ matrix.network }} asm-keccak jemalloc jemalloc-prof min-error-logs min-warn-logs min-info-logs min-debug-logs min-trace-logs"
|
||||
- name: Run clippy on binaries
|
||||
run: cargo clippy --bin "${{ matrix.binary }}" --workspace --features "${{ matrix.network }} asm-keccak jemalloc jemalloc-prof min-error-logs min-warn-logs min-info-logs min-debug-logs min-trace-logs"
|
||||
env:
|
||||
RUSTFLAGS: -D warnings
|
||||
- name: Run clippy on book binary sources
|
||||
run: cargo clippy --manifest-path book/sources/Cargo.toml --workspace --bins
|
||||
env:
|
||||
RUSTFLAGS: -D warnings
|
||||
|
||||
@ -128,7 +133,10 @@ jobs:
|
||||
- uses: dtolnay/rust-toolchain@nightly
|
||||
with:
|
||||
components: rustfmt
|
||||
- run: cargo fmt --all --check
|
||||
- name: Run fmt
|
||||
run: cargo fmt --all --check
|
||||
- name: Run fmt on book sources
|
||||
run: cargo fmt --manifest-path book/sources/Cargo.toml --all --check
|
||||
|
||||
udeps:
|
||||
name: udeps
|
||||
|
||||
5
.github/workflows/unit.yml
vendored
5
.github/workflows/unit.yml
vendored
@ -42,6 +42,11 @@ jobs:
|
||||
--workspace --exclude ef-tests \
|
||||
--partition hash:${{ matrix.partition }}/2 \
|
||||
-E "!kind(test)"
|
||||
- name: Run tests on book sources
|
||||
run: |
|
||||
cargo nextest run \
|
||||
--manifest-path book/sources/Cargo.toml --workspace \
|
||||
-E "!kind(test)"
|
||||
|
||||
state:
|
||||
name: Ethereum state tests
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@ -50,3 +50,6 @@ crates/storage/libmdbx-rs/mdbx-sys/libmdbx/cmake-build-debug
|
||||
|
||||
# Rust bug report
|
||||
rustc-ice-*
|
||||
|
||||
# Book sources should be able to build with the latest version
|
||||
book/sources/Cargo.lock
|
||||
|
||||
@ -148,6 +148,7 @@ members = [
|
||||
"testing/testing-utils",
|
||||
]
|
||||
default-members = ["bin/reth"]
|
||||
exclude = ["book/sources"]
|
||||
|
||||
# Explicitly set the resolver to version 2, which is the default for packages with edition >= 2021
|
||||
# https://doc.rust-lang.org/edition-guide/rust-2021/default-cargo-resolver.html
|
||||
|
||||
@ -14,19 +14,7 @@ cd my-exex
|
||||
And add Reth as a dependency in `Cargo.toml`
|
||||
|
||||
```toml
|
||||
[package]
|
||||
name = "my-exex"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
reth = { git = "https://github.com/paradigmxyz/reth.git" } # Reth
|
||||
reth-exex = { git = "https://github.com/paradigmxyz/reth.git" } # Execution Extensions
|
||||
reth-node-ethereum = { git = "https://github.com/paradigmxyz/reth.git" } # Ethereum Node implementation
|
||||
reth-tracing = { git = "https://github.com/paradigmxyz/reth.git" } # Logging
|
||||
|
||||
eyre = "0.6" # Easy error handling
|
||||
futures-util = "0.3" # Stream utilities for consuming notifications
|
||||
{{#include ../../sources/exex/hello-world/Cargo.toml}}
|
||||
```
|
||||
|
||||
### Default Reth node
|
||||
@ -34,15 +22,7 @@ futures-util = "0.3" # Stream utilities for consuming notifications
|
||||
Now, let's jump to our `main.rs` and start by initializing and launching a default Reth node
|
||||
|
||||
```rust,norun,noplayground,ignore
|
||||
use reth_node_ethereum::EthereumNode;
|
||||
|
||||
fn main() -> eyre::Result<()> {
|
||||
reth::cli::Cli::parse_args().run(|builder, _| async move {
|
||||
let handle = builder.node(EthereumNode::default()).launch().await?;
|
||||
|
||||
handle.wait_for_node_exit().await
|
||||
})
|
||||
}
|
||||
{{#include ../../sources/exex/hello-world/src/bin/1.rs}}
|
||||
```
|
||||
|
||||
You can already test that it works by running the binary and initializing the Holesky node in a custom datadir
|
||||
@ -63,26 +43,7 @@ $ cargo run -- init --chain holesky --datadir data
|
||||
The simplest ExEx is just an async function that never returns. We need to install it into our node
|
||||
|
||||
```rust,norun,noplayground,ignore
|
||||
use reth::api::FullNodeComponents;
|
||||
use reth_exex::{ExExContext, ExExEvent, ExExNotification};
|
||||
use reth_node_ethereum::EthereumNode;
|
||||
use reth_tracing::tracing::info;
|
||||
|
||||
async fn my_exex<Node: FullNodeComponents>(mut _ctx: ExExContext<Node>) -> eyre::Result<()> {
|
||||
loop {}
|
||||
}
|
||||
|
||||
fn main() -> eyre::Result<()> {
|
||||
reth::cli::Cli::parse_args().run(|builder, _| async move {
|
||||
let handle = builder
|
||||
.node(EthereumNode::default())
|
||||
.install_exex("my-exex", |ctx| async move { Ok(my_exex(ctx)) })
|
||||
.launch()
|
||||
.await?;
|
||||
|
||||
handle.wait_for_node_exit().await
|
||||
})
|
||||
}
|
||||
{{#include ../../sources/exex/hello-world/src/bin/2.rs}}
|
||||
```
|
||||
|
||||
See that unused `_ctx`? That's the context that we'll use to listen to new notifications coming from the main node,
|
||||
@ -103,46 +64,7 @@ If you try running a node with an ExEx that exits, the node will exit as well.
|
||||
Now, let's extend our simplest ExEx and start actually listening to new notifications, log them, and send events back to the main node
|
||||
|
||||
```rust,norun,noplayground,ignore
|
||||
use futures_util::StreamExt;
|
||||
use reth::api::FullNodeComponents;
|
||||
use reth_exex::{ExExContext, ExExEvent, ExExNotification};
|
||||
use reth_node_ethereum::EthereumNode;
|
||||
use reth_tracing::tracing::info;
|
||||
|
||||
async fn my_exex<Node: FullNodeComponents>(mut ctx: ExExContext<Node>) -> eyre::Result<()> {
|
||||
while let Some(notification) = ctx.notifications.next().await {
|
||||
match ¬ification {
|
||||
ExExNotification::ChainCommitted { new } => {
|
||||
info!(committed_chain = ?new.range(), "Received commit");
|
||||
}
|
||||
ExExNotification::ChainReorged { old, new } => {
|
||||
info!(from_chain = ?old.range(), to_chain = ?new.range(), "Received reorg");
|
||||
}
|
||||
ExExNotification::ChainReverted { old } => {
|
||||
info!(reverted_chain = ?old.range(), "Received revert");
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(committed_chain) = notification.committed_chain() {
|
||||
ctx.events
|
||||
.send(ExExEvent::FinishedHeight(committed_chain.tip().num_hash()))?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() -> eyre::Result<()> {
|
||||
reth::cli::Cli::parse_args().run(|builder, _| async move {
|
||||
let handle = builder
|
||||
.node(EthereumNode::default())
|
||||
.install_exex("my-exex", |ctx| async move { Ok(my_exex(ctx)) })
|
||||
.launch()
|
||||
.await?;
|
||||
|
||||
handle.wait_for_node_exit().await
|
||||
})
|
||||
}
|
||||
{{#include ../../sources/exex/hello-world/src/bin/3.rs}}
|
||||
```
|
||||
|
||||
Woah, there's a lot of new stuff here! Let's go through it step by step:
|
||||
|
||||
9
book/sources/Cargo.toml
Normal file
9
book/sources/Cargo.toml
Normal file
@ -0,0 +1,9 @@
|
||||
[workspace]
|
||||
members = [
|
||||
"exex/hello-world",
|
||||
]
|
||||
|
||||
# Explicitly set the resolver to version 2, which is the default for packages with edition >= 2021
|
||||
# https://doc.rust-lang.org/edition-guide/rust-2021/default-cargo-resolver.html
|
||||
resolver = "2"
|
||||
|
||||
13
book/sources/exex/hello-world/Cargo.toml
Normal file
13
book/sources/exex/hello-world/Cargo.toml
Normal file
@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "my-exex"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
reth = { git = "https://github.com/paradigmxyz/reth.git" } # Reth
|
||||
reth-exex = { git = "https://github.com/paradigmxyz/reth.git" } # Execution Extensions
|
||||
reth-node-ethereum = { git = "https://github.com/paradigmxyz/reth.git" } # Ethereum Node implementation
|
||||
reth-tracing = { git = "https://github.com/paradigmxyz/reth.git" } # Logging
|
||||
|
||||
eyre = "0.6" # Easy error handling
|
||||
futures-util = "0.3" # Stream utilities for consuming notifications
|
||||
9
book/sources/exex/hello-world/src/bin/1.rs
Normal file
9
book/sources/exex/hello-world/src/bin/1.rs
Normal file
@ -0,0 +1,9 @@
|
||||
use reth_node_ethereum::EthereumNode;
|
||||
|
||||
fn main() -> eyre::Result<()> {
|
||||
reth::cli::Cli::parse_args().run(|builder, _| async move {
|
||||
let handle = builder.node(EthereumNode::default()).launch().await?;
|
||||
|
||||
handle.wait_for_node_exit().await
|
||||
})
|
||||
}
|
||||
20
book/sources/exex/hello-world/src/bin/2.rs
Normal file
20
book/sources/exex/hello-world/src/bin/2.rs
Normal file
@ -0,0 +1,20 @@
|
||||
use reth::api::FullNodeComponents;
|
||||
use reth_exex::ExExContext;
|
||||
use reth_node_ethereum::EthereumNode;
|
||||
|
||||
async fn my_exex<Node: FullNodeComponents>(mut _ctx: ExExContext<Node>) -> eyre::Result<()> {
|
||||
#[allow(clippy::empty_loop)]
|
||||
loop {}
|
||||
}
|
||||
|
||||
fn main() -> eyre::Result<()> {
|
||||
reth::cli::Cli::parse_args().run(|builder, _| async move {
|
||||
let handle = builder
|
||||
.node(EthereumNode::default())
|
||||
.install_exex("my-exex", |ctx| async move { Ok(my_exex(ctx)) })
|
||||
.launch()
|
||||
.await?;
|
||||
|
||||
handle.wait_for_node_exit().await
|
||||
})
|
||||
}
|
||||
39
book/sources/exex/hello-world/src/bin/3.rs
Normal file
39
book/sources/exex/hello-world/src/bin/3.rs
Normal file
@ -0,0 +1,39 @@
|
||||
use futures_util::TryStreamExt;
|
||||
use reth::api::FullNodeComponents;
|
||||
use reth_exex::{ExExContext, ExExEvent, ExExNotification};
|
||||
use reth_node_ethereum::EthereumNode;
|
||||
use reth_tracing::tracing::info;
|
||||
|
||||
async fn my_exex<Node: FullNodeComponents>(mut ctx: ExExContext<Node>) -> eyre::Result<()> {
|
||||
while let Some(notification) = ctx.notifications.try_next().await? {
|
||||
match ¬ification {
|
||||
ExExNotification::ChainCommitted { new } => {
|
||||
info!(committed_chain = ?new.range(), "Received commit");
|
||||
}
|
||||
ExExNotification::ChainReorged { old, new } => {
|
||||
info!(from_chain = ?old.range(), to_chain = ?new.range(), "Received reorg");
|
||||
}
|
||||
ExExNotification::ChainReverted { old } => {
|
||||
info!(reverted_chain = ?old.range(), "Received revert");
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(committed_chain) = notification.committed_chain() {
|
||||
ctx.events.send(ExExEvent::FinishedHeight(committed_chain.tip().num_hash()))?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() -> eyre::Result<()> {
|
||||
reth::cli::Cli::parse_args().run(|builder, _| async move {
|
||||
let handle = builder
|
||||
.node(EthereumNode::default())
|
||||
.install_exex("my-exex", |ctx| async move { Ok(my_exex(ctx)) })
|
||||
.launch()
|
||||
.await?;
|
||||
|
||||
handle.wait_for_node_exit().await
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user