lssa/lez/sequencer/service/src/bin/configure_channel.rs
erhant 8d09ffd733 feat(sequencer): two-tier chain state and multi-sequencer support
Decentralized-sequencing foundation: a shared chain_state crate (two-tier
head/final ChainState, apply_block, AcceptOutcome, StallReason, and the
absorbed channel-consistency machinery), turn-gated block production, the
publisher follow path for adopted/orphaned/finalized peer blocks, and
persistence that keeps disk order equal to apply order under the chain lock.

Rebased onto dev after #600/#606: chain_consistency is absorbed into
chain_state, the sequencer bootstrap's verify_and_reconstruct is re-wired
onto the two-tier ChainState (reconstruction applies channel history
through the final tier and persists via the follow-path primitives), and
test fixtures adopt the SequencerSetup builder extended with
with_bedrock_signing_key.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 11:43:57 +03:00

72 lines
2.3 KiB
Rust

//! Posts a `ChannelConfig` op (accredited keys + rotation params) to bedrock,
//! signed with `<home>/bedrock_signing_key`, without booting the sequencer.
//!
//! Authorization is holding the admin key file — the L1 rejects non-admin
//! signers. Acceptance is asynchronous: a rejection only shows up in node
//! logs and on-chain behavior.
use std::path::PathBuf;
use anyhow::{Context as _, Result, anyhow};
use clap::Parser;
use sequencer_core::block_publisher::{Ed25519PublicKey, post_channel_config};
#[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>,
/// Accredited ed25519 public keys (hex), admin (this node's key) first.
#[clap(long, required = true, value_delimiter = ',')]
keys: Vec<String>,
/// Slots a sequencer's posting turn lasts.
#[clap(long)]
posting_timeframe: u32,
/// Slots after which a stalled turn can be taken over.
#[clap(long)]
posting_timeout: u32,
/// Signatures required for future config changes.
#[clap(long, default_value_t = 1)]
configuration_threshold: u16,
/// Signatures required for channel withdrawals.
#[clap(long, default_value_t = 1)]
withdraw_threshold: u16,
}
#[tokio::main]
async fn main() -> Result<()> {
env_logger::init();
let args = Args::parse();
let config = sequencer_service::SequencerConfig::from_path(&args.config_path)?;
let home = args.home.unwrap_or(config.home);
let signing_key =
sequencer_core::load_or_create_signing_key(&home.join("bedrock_signing_key"))?;
let keys = args
.keys
.iter()
.map(|key| parse_key(key))
.collect::<Result<Vec<_>>>()?;
post_channel_config(
&config.bedrock_config,
&signing_key,
keys,
args.posting_timeframe,
args.posting_timeout,
args.configuration_threshold,
args.withdraw_threshold,
)
.await
}
fn parse_key(hex_key: &str) -> Result<Ed25519PublicKey> {
let mut bytes = [0_u8; 32];
hex::decode_to_slice(hex_key, &mut bytes)
.with_context(|| format!("Invalid hex-encoded key {hex_key}"))?;
Ed25519PublicKey::from_bytes(&bytes).map_err(|err| anyhow!("Invalid Ed25519 public key: {err}"))
}