feat(sequencer): multi-sequencer demo ergonomics (--home override, pubkey helper, demo recipes)

This commit is contained in:
erhant 2026-07-15 13:00:46 +03:00
parent 1a5da3d925
commit c9e3bf2a05
6 changed files with 68 additions and 7 deletions

View File

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

View File

@ -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
);
}
}
}
}

View File

@ -134,6 +134,10 @@ impl<BP: BlockPublisherTrait> SequencerCore<BP> {
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<Ed25519Key> {
pub fn load_or_create_signing_key(path: &Path) -> Result<Ed25519Key> {
if path.exists() {
let key_bytes = std::fs::read(path)?;

View File

@ -1,6 +1,7 @@
[package]
name = "sequencer_service"
version = "0.1.0"
default-run = "sequencer_service"
edition = "2024"
license = { workspace = true }

View File

@ -0,0 +1,35 @@
//! Prints the sequencer's bedrock signing public key (hex) without booting it.
//!
//! Loads `<home>/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<PathBuf>,
}
#[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(())
}

View File

@ -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<PathBuf>,
}
#[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! {