Skip to content

feat(l2): monitor for ethrex L2 #3410

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 44 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
60ce046
Share Sequencer shared state with RPC API
ilitteri Jun 30, 2025
22357d1
Add `debug_nodeStatus` endpoint
ilitteri Jun 30, 2025
74ff66f
Add `txpool_content` to `EthClient`
ilitteri Jun 30, 2025
e18be3a
Add initial implementation of monitor
ilitteri Jun 30, 2025
1ec5c47
Add addresses
ilitteri Jun 30, 2025
0156931
Merge branch 'main' of github.com:lambdaclass/ethrex into based_monitor
ilitteri Jun 30, 2025
83fd03a
Move monitor into bin dir
ilitteri Jun 30, 2025
23bdb9b
Remove src dir
ilitteri Jun 30, 2025
98b4989
Run in based/non-based mode
ilitteri Jun 30, 2025
1730bd7
Merge monitor with ethrex L2
ilitteri Jul 1, 2025
942b3ee
Add L1 to L2 messages table
ilitteri Jul 2, 2025
f8ec9af
Merge branch 'main' of github.com:lambdaclass/ethrex into based_monitor
ilitteri Jul 2, 2025
ecdfbf5
fix merge
ilitteri Jul 2, 2025
f4719e1
Add batches table
ilitteri Jul 2, 2025
e454c9b
Adjust mempool table
ilitteri Jul 2, 2025
aff56ff
Address some TODOs
ilitteri Jul 2, 2025
034a413
Add L2 to L1 messages table
ilitteri Jul 3, 2025
1d956cf
First refactor
ilitteri Jul 3, 2025
58fd724
Refactor rendering
ilitteri Jul 3, 2025
c72e647
Refactor rendering - leftovers
ilitteri Jul 3, 2025
caf99de
Pass store and rollup store to ethrex monitor
ilitteri Jul 3, 2025
f1f4cd3
Replace rollup_client using store and rollup_store in the global chai…
ilitteri Jul 3, 2025
0c5e483
Replace rollup_client using store and rollup_store in the batches widget
ilitteri Jul 3, 2025
e2c262c
Replace rollup_client using store and store in the blocks widget
ilitteri Jul 3, 2025
47609be
Handle multiple topics in EthClient::get_logs
ilitteri Jul 3, 2025
401a9a2
Prune extra log search
ilitteri Jul 3, 2025
93be943
Update default tick_rate
ilitteri Jul 3, 2025
5ede25f
Update current items in batches widget
ilitteri Jul 4, 2025
8210224
Merge branch 'main' of github.com:lambdaclass/ethrex into based_monitor
ilitteri Jul 4, 2025
f73ece8
Fix merge
ilitteri Jul 4, 2025
3c6c16f
Fix merge
ilitteri Jul 4, 2025
b5560ef
Fix merge
ilitteri Jul 4, 2025
eb0a67e
Rename PrivilegeL2Transaction field
ilitteri Jul 4, 2025
5ccb365
Add fix in batches table
ilitteri Jul 4, 2025
d913966
Fix l1 to l2 messages
ilitteri Jul 4, 2025
f776a38
Ad tx type to mempool widget
ilitteri Jul 4, 2025
3c8b19e
Display kind before status for l1 to l2 messages
ilitteri Jul 4, 2025
3be3008
Refactor addition of new items
ilitteri Jul 4, 2025
50d86ba
Update current items in l1 to l2 messages widget
ilitteri Jul 4, 2025
7f1adcc
Update current items in l2 to l1 messages widget
ilitteri Jul 4, 2025
b9fe384
Initialize monitor optionally until stabler versions
ilitteri Jul 4, 2025
35d7934
Use store in l1 to l2 messages widget
ilitteri Jul 4, 2025
c8303ef
Use store in node status widget
ilitteri Jul 4, 2025
790db0d
fixes
ilitteri Jul 4, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
337 changes: 332 additions & 5 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ futures = "0.3.31"
spawned-concurrency = {git = "https://github.com/lambdaclass/spawned.git", tag = "v0.1.2-alpha"}
spawned-rt = {git = "https://github.com/lambdaclass/spawned.git", tag = "v0.1.2-alpha"}
lambdaworks-crypto = "0.11.0"
tui-logger = { version = "0.17.3", features = ["tracing-support"] }

[patch.crates-io]
secp256k1 = { git = "https://github.com/sp1-patches/rust-secp256k1", tag = "patch-0.29.1-sp1-5.0.0" }
1 change: 1 addition & 0 deletions cmd/ethrex/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ secp256k1 = { workspace = true }
keccak-hash.workspace = true
reqwest.workspace = true
itertools = "0.14.0"
tui-logger.workspace = true

cfg-if = "1.0.0"

Expand Down
4 changes: 2 additions & 2 deletions cmd/ethrex/ethrex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,12 @@ async fn server_shutdown(
async fn main() -> eyre::Result<()> {
let CLI { opts, command } = CLI::parse();

init_tracing(&opts);

if let Some(subcommand) = command {
return subcommand.run(&opts).await;
}

init_tracing(&opts);

let data_dir = set_datadir(&opts.datadir);

let network = get_network(&opts);
Expand Down
19 changes: 17 additions & 2 deletions cmd/ethrex/l2/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ use ethrex_common::{
Address, U256,
types::{BYTES_PER_BLOB, BlobsBundle, BlockHeader, batch::Batch, bytes_from_blob},
};
use ethrex_l2::SequencerConfig;
use ethrex_l2::{
SequencerConfig,
based::sequencer_state::{SequencerState, SequencerStatus},
};
use ethrex_l2_common::calldata::Value;
use ethrex_l2_common::l1_messages::get_l1_message_hash;
use ethrex_l2_common::state_diff::StateDiff;
Expand Down Expand Up @@ -127,6 +130,8 @@ impl Command {
panic!("L2 Doesn't support REVM, use LEVM instead.");
}

l2::initializers::init_tracing(&opts);

let data_dir = set_datadir(&opts.node_opts.datadir);
let rollup_store_dir = data_dir.clone() + "/rollup_store";

Expand Down Expand Up @@ -156,6 +161,14 @@ impl Command {

let cancel_token = tokio_util::sync::CancellationToken::new();

let initial_status = if opts.sequencer_opts.based {
SequencerStatus::default()
} else {
SequencerStatus::Sequencing
};

let shared_state = SequencerState::from(initial_status);

l2::initializers::init_rpc_api(
&opts.node_opts,
&opts,
Expand All @@ -167,6 +180,7 @@ impl Command {
cancel_token.clone(),
tracker.clone(),
rollup_store.clone(),
shared_state.clone(),
)
.await;

Expand Down Expand Up @@ -203,6 +217,7 @@ impl Command {
store,
rollup_store,
blockchain,
shared_state,
l2_sequencer_cfg,
#[cfg(feature = "metrics")]
format!(
Expand Down Expand Up @@ -267,7 +282,7 @@ impl Command {
current_block,
current_block,
contract_address,
event_signature,
vec![event_signature],
)
.await?;

Expand Down
23 changes: 22 additions & 1 deletion cmd/ethrex/l2/initializers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::sync::Arc;

use ethrex_blockchain::Blockchain;
use ethrex_common::Address;
use ethrex_l2::based::sequencer_state::SequencerState;
use ethrex_p2p::kademlia::KademliaTable;
use ethrex_p2p::peer_handler::PeerHandler;
use ethrex_p2p::sync_manager::SyncManager;
Expand All @@ -13,9 +14,12 @@ use tokio::sync::Mutex;
use tokio_util::sync::CancellationToken;
use tokio_util::task::TaskTracker;
use tracing::warn;
use tracing_subscriber::EnvFilter;
use tracing_subscriber::layer::SubscriberExt;
use tui_logger::{LevelFilter, TuiTracingSubscriberLayer};

use crate::cli::Options as L1Options;
use crate::initializers::{get_authrpc_socket_addr, get_http_socket_addr};
use crate::initializers::{self, get_authrpc_socket_addr, get_http_socket_addr};
use crate::l2::L2Options;
use crate::utils::{get_client_version, read_jwtsecret_file};

Expand All @@ -31,6 +35,7 @@ pub async fn init_rpc_api(
cancel_token: CancellationToken,
tracker: TaskTracker,
rollup_store: StoreRollup,
initial_state: SequencerState,
) {
let peer_handler = PeerHandler::new(peer_table);

Expand Down Expand Up @@ -58,6 +63,7 @@ pub async fn init_rpc_api(
get_valid_delegation_addresses(l2_opts),
l2_opts.sponsor_private_key,
rollup_store,
initial_state,
);

tracker.spawn(rpc_api);
Expand Down Expand Up @@ -114,3 +120,18 @@ pub fn init_metrics(opts: &L1Options, tracker: TaskTracker) {
);
tracker.spawn(metrics_api);
}

pub fn init_tracing(opts: &L2Options) {
if opts.sequencer_opts.monitor {
let level_filter = EnvFilter::builder()
.parse_lossy("debug,tower_http::trace=debug,reqwest_tracing=off,hyper=off,libsql=off,ethrex::initializers=off,ethrex::l2::initializers=off,ethrex::l2::command=off");
let subscriber = tracing_subscriber::registry()
.with(TuiTracingSubscriberLayer)
.with(level_filter);
tracing::subscriber::set_global_default(subscriber)
.expect("setting default subscriber failed");
tui_logger::init_logger(LevelFilter::max()).expect("Failed to initialize tui_logger");
} else {
initializers::init_tracing(&opts.node_opts);
}
}
26 changes: 25 additions & 1 deletion cmd/ethrex/l2/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ use ethrex_common::Address;
use ethrex_l2::{
BasedConfig, BlockFetcherConfig, BlockProducerConfig, CommitterConfig, EthConfig,
L1WatcherConfig, ProofCoordinatorConfig, SequencerConfig, StateUpdaterConfig,
sequencer::{configs::AlignedConfig, utils::resolve_aligned_network},
sequencer::{
configs::{AlignedConfig, MonitorConfig},
utils::resolve_aligned_network,
},
};
use ethrex_rpc::clients::eth::{
BACKOFF_FACTOR, MAX_NUMBER_OF_RETRIES, MAX_RETRY_DELAY, MIN_RETRY_DELAY,
Expand Down Expand Up @@ -62,6 +65,8 @@ pub struct SequencerOptions {
pub based_opts: BasedOptions,
#[command(flatten)]
pub aligned_opts: AlignedOptions,
#[command(flatten)]
pub monitor_opts: MonitorOptions,
#[arg(
long = "validium",
default_value = "false",
Expand All @@ -79,6 +84,14 @@ pub struct SequencerOptions {
help_heading = "Based options"
)]
pub based: bool,
#[clap(
long,
default_value = "false",
value_name = "BOOLEAN",
env = "ETHREX_MONITOR",
help_heading = "Sequencer options"
)]
pub monitor: bool,
}

impl From<SequencerOptions> for SequencerConfig {
Expand Down Expand Up @@ -154,6 +167,10 @@ impl From<SequencerOptions> for SequencerConfig {
fee_estimate: opts.aligned_opts.fee_estimate,
aligned_sp1_elf_path: opts.aligned_opts.aligned_sp1_elf_path.unwrap_or_default(),
},
monitor: MonitorConfig {
enabled: opts.monitor,
tick_rate: opts.monitor_opts.tick_rate,
},
}
}
}
Expand Down Expand Up @@ -549,3 +566,10 @@ pub struct BlockFetcherOptions {
)]
pub fetch_block_step: u64,
}

#[derive(Parser, Default)]
pub struct MonitorOptions {
/// time in ms between two ticks.
#[arg(short, long, default_value_t = 1000)]
tick_rate: u64,
}
21 changes: 17 additions & 4 deletions crates/common/types/transaction.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::cmp::min;
use std::{cmp::min, fmt::Display};

use bytes::Bytes;
use ethereum_types::{Address, H256, U256};
Expand Down Expand Up @@ -274,6 +274,19 @@ impl From<TxType> for u8 {
}
}

impl Display for TxType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
TxType::Legacy => write!(f, "Legacy"),
TxType::EIP2930 => write!(f, "EIP2930"),
TxType::EIP1559 => write!(f, "EIP1559"),
TxType::EIP4844 => write!(f, "EIP4844"),
TxType::EIP7702 => write!(f, "EIP7702"),
TxType::Privileged => write!(f, "Privileged"),
}
}
}

pub trait Signable {
/// Both sign and sign_in_place return error when the payload hash calculated that has to
/// be signed is not exactly 32 bytes long. Currently it's an unreachable error
Expand Down Expand Up @@ -1863,7 +1876,7 @@ mod serde_impl {
.collect::<Vec<_>>(),
)?;
struct_serializer.serialize_field("chainId", &format!("{:#x}", self.chain_id))?;
struct_serializer.serialize_field("from", &self.from)?;
struct_serializer.serialize_field("sender", &self.from)?;
struct_serializer.end()
}
}
Expand Down Expand Up @@ -1925,7 +1938,7 @@ mod serde_impl {
)
.map(Transaction::PrivilegedL2Transaction)
.map_err(|e| {
serde::de::Error::custom(format!("Couldn't Deserialize Privileged {e}"))
serde::de::Error::custom(format!("Couldn't Deserialize Privileged: {e}"))
}),
}
}
Expand Down Expand Up @@ -2164,7 +2177,7 @@ mod serde_impl {
.into_iter()
.map(|v| (v.address, v.storage_keys))
.collect::<Vec<_>>(),
from: deserialize_field::<Address, D>(&mut map, "from")?,
from: deserialize_field::<Address, D>(&mut map, "sender")?,
})
}
}
Expand Down
12 changes: 10 additions & 2 deletions crates/l2/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ ethrex-l2-common.workspace = true
ethrex-dev = { path = "../../crates/blockchain/dev", default-features = false }
ethrex-metrics = { path = "../blockchain/metrics", default-features = false }
ethrex-sdk = { path = "./sdk" }
ethrex-p2p.workspace = true
hex.workspace = true
bytes.workspace = true
jsonwebtoken.workspace = true
Expand All @@ -43,11 +44,18 @@ lazy_static.workspace = true
aligned-sdk = { git = "https://github.com/yetanotherco/aligned_layer", tag = "v0.16.1" }
ethers = "2.0"
cfg-if.workspace = true
chrono = "0.4.41"
clap.workspace = true
crossterm = "0.29.0"
ratatui = "0.29.0"
tui-big-text = "0.7.1"
tui-scrollview = "0.5.1"
tui-logger.workspace = true
tabwriter = "1.4.1"
color-eyre = "0.6.5"

zkvm_interface = { path = "./prover/zkvm/interface/" }

[dev-dependencies]
rand = "0.8.5"

[build-dependencies]
vergen-git2 = { version = "1.0.7" }
Expand Down
2 changes: 1 addition & 1 deletion crates/l2/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ build-prover:
--bin ethrex_prover

rm-db-l2: ## 🛑 Removes the DB used by the L2
cargo run --release --manifest-path ../../Cargo.toml --bin ethrex --features l2 -- l2 removedb --datadir ${ethrex_L2_DEV_LIBMDBX} --force
cargo run --release --manifest-path ../../Cargo.toml --bin ethrex -- l2 removedb --datadir ${ethrex_L2_DEV_LIBMDBX} --force

test: ## 🚧 Runs the L2's integration test, run `make init` and in a new terminal make test
cargo test l2_integration_test --release -- --nocapture || (echo "The tests have failed.\n Is the L2 running? To start it, run:\n make rm-db-l1; make rm-db-l2; make restart" ; exit 1)
Expand Down
4 changes: 2 additions & 2 deletions crates/l2/based/block_fetcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ async fn get_logs(
state.last_l1_block_fetched + 1,
new_last_l1_fetched_block,
state.on_chain_proposer_address,
keccak(b"BatchCommitted(uint256,bytes32)"),
vec![keccak(b"BatchCommitted(uint256,bytes32)")],
)
.await?;

Expand All @@ -253,7 +253,7 @@ async fn get_logs(
state.last_l1_block_fetched + 1,
new_last_l1_fetched_block,
state.on_chain_proposer_address,
keccak(b"BatchVerified(uint256)"),
vec![keccak(b"BatchVerified(uint256)")],
)
.await?;

Expand Down
3 changes: 2 additions & 1 deletion crates/l2/based/sequencer_state.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::sync::Arc;

use serde::{Deserialize, Serialize};
use tokio::sync::Mutex;

#[derive(Debug, Clone)]
Expand All @@ -21,7 +22,7 @@ impl From<SequencerStatus> for SequencerState {
}
}

#[derive(Debug, Default, Clone)]
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub enum SequencerStatus {
Sequencing,
#[default]
Expand Down
1 change: 1 addition & 0 deletions crates/l2/l2.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod based;
pub mod errors;
pub mod monitor;
pub mod sequencer;
pub mod utils;

Expand Down
Loading
Loading