From c9e3bf2a055d8b56e70ea1738a32d26a72738911 Mon Sep 17 00:00:00 2001 From: erhant Date: Wed, 15 Jul 2026 13:00:46 +0300 Subject: [PATCH] feat(sequencer): multi-sequencer demo ergonomics (`--home` override, pubkey helper, demo recipes) --- Justfile | 8 +++-- lez/sequencer/core/src/block_publisher.rs | 10 +++++- lez/sequencer/core/src/lib.rs | 6 +++- lez/sequencer/service/Cargo.toml | 1 + .../service/src/bin/bedrock_pubkey.rs | 35 +++++++++++++++++++ lez/sequencer/service/src/main.rs | 15 ++++++-- 6 files changed, 68 insertions(+), 7 deletions(-) create mode 100644 lez/sequencer/service/src/bin/bedrock_pubkey.rs diff --git a/Justfile b/Justfile index cf7c833e..93c2f8ab 100644 --- a/Justfile +++ b/Justfile @@ -58,15 +58,17 @@ run-bedrock: docker compose up # Run Sequencer. Run with RISC0_DEV_MODE=1 to disable proof verification for faster iteration. +# Optional home/port let a second instance run off the same config, e.g. +# `just run-sequencer "" "$TMPDIR/lez-sequencer2" 3041` for the multi-sequencer demo. [working-directory: 'lez/sequencer/service'] -run-sequencer standalone="": +run-sequencer standalone="" home="" port="3040": @echo "๐Ÿง  Running sequencer" @if [ "{{standalone}}" = "standalone" ]; then \ echo "๐Ÿงช Running in standalone mode"; \ - RUST_LOG=info cargo run --features standalone --release -p sequencer_service configs/debug/sequencer_config.json; \ + RUST_LOG=info cargo run --features standalone --release -p sequencer_service -- configs/debug/sequencer_config.json --port {{port}} {{ if home != "" { "--home " + quote(home) } else { "" } }}; \ else \ echo "๐Ÿš€ Running in normal mode"; \ - RUST_LOG=info cargo run --release -p sequencer_service configs/debug/sequencer_config.json; \ + RUST_LOG=info cargo run --release -p sequencer_service -- configs/debug/sequencer_config.json --port {{port}} {{ if home != "" { "--home " + quote(home) } else { "" } }}; \ fi # Run Indexer. Run with RISC0_DEV_MODE=1 to disable proof verification for faster iteration. diff --git a/lez/sequencer/core/src/block_publisher.rs b/lez/sequencer/core/src/block_publisher.rs index 105e0c77..0bf32719 100644 --- a/lez/sequencer/core/src/block_publisher.rs +++ b/lez/sequencer/core/src/block_publisher.rs @@ -301,7 +301,15 @@ impl BlockPublisherTrait for ZoneSdkPublisher { }) .await; } - Event::Ready | Event::TurnNotification { .. } => {} + Event::Ready => {} + Event::TurnNotification { notification } => { + info!( + "Turn update: our_turn={}, starting_slot={:?}, ends_at_slot={:?}", + notification.our_turn_to_write, + notification.starting_slot, + notification.ends_at_slot + ); + } } } } diff --git a/lez/sequencer/core/src/lib.rs b/lez/sequencer/core/src/lib.rs index 19bc7acf..3ebc8abf 100644 --- a/lez/sequencer/core/src/lib.rs +++ b/lez/sequencer/core/src/lib.rs @@ -134,6 +134,10 @@ impl SequencerCore { let bedrock_signing_key = load_or_create_signing_key(&config.home.join("bedrock_signing_key")) .expect("Failed to load or create bedrock signing key"); + info!( + "Bedrock signing public key: {}", + hex::encode(bedrock_signing_key.public_key().to_bytes()) + ); let (store, state, _genesis_block) = Self::open_or_create_store(&config); @@ -1065,7 +1069,7 @@ fn withdraw_event_reconciliation_key( } /// Load signing key from file or generate a new one if it doesn't exist. -fn load_or_create_signing_key(path: &Path) -> Result { +pub fn load_or_create_signing_key(path: &Path) -> Result { if path.exists() { let key_bytes = std::fs::read(path)?; diff --git a/lez/sequencer/service/Cargo.toml b/lez/sequencer/service/Cargo.toml index 94617bd9..338aac0d 100644 --- a/lez/sequencer/service/Cargo.toml +++ b/lez/sequencer/service/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "sequencer_service" version = "0.1.0" +default-run = "sequencer_service" edition = "2024" license = { workspace = true } diff --git a/lez/sequencer/service/src/bin/bedrock_pubkey.rs b/lez/sequencer/service/src/bin/bedrock_pubkey.rs new file mode 100644 index 00000000..ad602be6 --- /dev/null +++ b/lez/sequencer/service/src/bin/bedrock_pubkey.rs @@ -0,0 +1,35 @@ +//! Prints the sequencer's bedrock signing public key (hex) without booting it. +//! +//! Loads `/bedrock_signing_key` from the given sequencer config, creating +//! the key if it doesn't exist yet, so that a node can be accredited into the +//! channel committee before its first boot. + +use std::path::PathBuf; + +use anyhow::Result; +use clap::Parser; + +#[derive(Debug, Parser)] +#[clap(version)] +struct Args { + #[clap(name = "config")] + config_path: PathBuf, + /// Override the config's home directory, matching the sequencer's --home. + #[clap(long)] + home: Option, +} + +#[expect( + clippy::print_stdout, + reason = "the hex pubkey on stdout is this binary's output" +)] +fn main() -> Result<()> { + let Args { config_path, home } = Args::parse(); + + let config = sequencer_service::SequencerConfig::from_path(&config_path)?; + let home = home.unwrap_or(config.home); + let key = sequencer_core::load_or_create_signing_key(&home.join("bedrock_signing_key"))?; + println!("{}", hex::encode(key.public_key().to_bytes())); + + Ok(()) +} diff --git a/lez/sequencer/service/src/main.rs b/lez/sequencer/service/src/main.rs index 8b577bb8..4dede6d2 100644 --- a/lez/sequencer/service/src/main.rs +++ b/lez/sequencer/service/src/main.rs @@ -12,6 +12,10 @@ struct Args { config_path: PathBuf, #[clap(short, long, default_value = "3040")] port: u16, + /// Override the config's home directory (`RocksDB` + bedrock signing key), + /// so multiple instances can share one config file. + #[clap(long)] + home: Option, } #[tokio::main] @@ -22,13 +26,20 @@ struct Args { async fn main() -> Result<()> { env_logger::init(); - let Args { config_path, port } = Args::parse(); + let Args { + config_path, + port, + home, + } = Args::parse(); // TODO: handle this cancellation token more gracefully within Sequencer service // similar to how we do in Indexer let cancellation_token = listen_for_shutdown_signal(); - let config = sequencer_service::SequencerConfig::from_path(&config_path)?; + let mut config = sequencer_service::SequencerConfig::from_path(&config_path)?; + if let Some(home) = home { + config.home = home; + } let sequencer_handle = sequencer_service::run(config, port).await?; tokio::select! {