feat: add exex for in memory state (#8108)

This commit is contained in:
Matthias Seitz
2024-05-06 13:08:20 +02:00
committed by GitHub
parent f83a872dd6
commit 68920b830f
5 changed files with 83 additions and 8 deletions

12
Cargo.lock generated
View File

@ -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"

View File

@ -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",

View File

@ -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

View 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

View 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 &notification {
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
})
}