mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: add exex for in memory state (#8108)
This commit is contained in:
12
Cargo.lock
generated
12
Cargo.lock
generated
@ -2912,6 +2912,18 @@ dependencies = [
|
|||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "exex-in-memory-state"
|
||||||
|
version = "0.0.0"
|
||||||
|
dependencies = [
|
||||||
|
"eyre",
|
||||||
|
"reth",
|
||||||
|
"reth-exex",
|
||||||
|
"reth-node-api",
|
||||||
|
"reth-node-ethereum",
|
||||||
|
"reth-tracing",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "exex-minimal"
|
name = "exex-minimal"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
|
|||||||
@ -87,9 +87,7 @@ members = [
|
|||||||
"examples/txpool-tracing/",
|
"examples/txpool-tracing/",
|
||||||
"examples/polygon-p2p/",
|
"examples/polygon-p2p/",
|
||||||
"examples/custom-inspector/",
|
"examples/custom-inspector/",
|
||||||
"examples/exex/minimal/",
|
"examples/exex/*",
|
||||||
"examples/exex/op-bridge/",
|
|
||||||
"examples/exex/rollup/",
|
|
||||||
"examples/db-access",
|
"examples/db-access",
|
||||||
"testing/ef-tests/",
|
"testing/ef-tests/",
|
||||||
"testing/testing-utils",
|
"testing/testing-utils",
|
||||||
|
|||||||
@ -23,11 +23,12 @@ to make a PR!
|
|||||||
|
|
||||||
## ExEx
|
## ExEx
|
||||||
|
|
||||||
| Example | Description |
|
| Example | Description |
|
||||||
| ---------------------------------- | --------------------------------------------------------------------------------- |
|
|-------------------------------------------|-----------------------------------------------------------------------------------|
|
||||||
| [Minimal ExEx](./exex/minimal) | Illustrates how to build a simple ExEx |
|
| [Minimal ExEx](./exex/minimal) | Illustrates how to build a simple ExEx |
|
||||||
| [OP Bridge ExEx](./exex/op-bridge) | Illustrates an ExEx that decodes Optimism deposit and withdrawal receipts from L1 |
|
| [OP Bridge ExEx](./exex/op-bridge) | Illustrates an ExEx that decodes Optimism deposit and withdrawal receipts from L1 |
|
||||||
| [Rollup](./exex/rollup) | Illustrates a rollup ExEx that derives the state from L1 |
|
| [Rollup](./exex/rollup) | Illustrates a rollup ExEx that derives the state from L1 |
|
||||||
|
| [In Memory State](./exex/in-memory-state) | Illustrates an ExEx that tracks the plain state in memory |
|
||||||
|
|
||||||
## RPC
|
## RPC
|
||||||
|
|
||||||
|
|||||||
15
examples/exex/in-memory-state/Cargo.toml
Normal file
15
examples/exex/in-memory-state/Cargo.toml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
[package]
|
||||||
|
name = "exex-in-memory-state"
|
||||||
|
version = "0.0.0"
|
||||||
|
publish = false
|
||||||
|
edition.workspace = true
|
||||||
|
license.workspace = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
reth.workspace = true
|
||||||
|
reth-exex.workspace = true
|
||||||
|
reth-node-api.workspace = true
|
||||||
|
reth-node-ethereum.workspace = true
|
||||||
|
reth-tracing.workspace = true
|
||||||
|
|
||||||
|
eyre.workspace = true
|
||||||
49
examples/exex/in-memory-state/src/main.rs
Normal file
49
examples/exex/in-memory-state/src/main.rs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#![warn(unused_crate_dependencies)]
|
||||||
|
|
||||||
|
use reth::providers::BundleStateWithReceipts;
|
||||||
|
use reth_exex::{ExExContext, ExExEvent, ExExNotification};
|
||||||
|
use reth_node_api::FullNodeComponents;
|
||||||
|
use reth_node_ethereum::EthereumNode;
|
||||||
|
use reth_tracing::tracing::info;
|
||||||
|
|
||||||
|
/// An ExEx that keeps track of the entire state in memory
|
||||||
|
async fn track_state<Node: FullNodeComponents>(mut ctx: ExExContext<Node>) -> eyre::Result<()> {
|
||||||
|
// keeps the entire plain state of the chain in memory
|
||||||
|
let mut state = BundleStateWithReceipts::default();
|
||||||
|
|
||||||
|
while let Some(notification) = ctx.notifications.recv().await {
|
||||||
|
match ¬ification {
|
||||||
|
ExExNotification::ChainCommitted { new } => {
|
||||||
|
info!(committed_chain = ?new.range(), "Received commit");
|
||||||
|
}
|
||||||
|
ExExNotification::ChainReorged { old, new } => {
|
||||||
|
// revert to block before the reorg
|
||||||
|
state.revert_to(new.first().number - 1);
|
||||||
|
info!(from_chain = ?old.range(), to_chain = ?new.range(), "Received reorg");
|
||||||
|
}
|
||||||
|
ExExNotification::ChainReverted { old } => {
|
||||||
|
state.revert_to(old.first().number - 1);
|
||||||
|
info!(reverted_chain = ?old.range(), "Received revert");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(committed_chain) = notification.committed_chain() {
|
||||||
|
// extend the state with the new chain
|
||||||
|
state.extend(committed_chain.state().clone());
|
||||||
|
ctx.events.send(ExExEvent::FinishedHeight(committed_chain.tip().number))?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> eyre::Result<()> {
|
||||||
|
reth::cli::Cli::parse_args().run(|builder, _| async move {
|
||||||
|
let handle = builder
|
||||||
|
.node(EthereumNode::default())
|
||||||
|
.install_exex("in-memory-state", |ctx| async move { Ok(track_state(ctx)) })
|
||||||
|
.launch()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
handle.wait_for_node_exit().await
|
||||||
|
})
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user