simplified for single sequencer

This commit is contained in:
kashepavadan 2026-06-24 11:12:36 -04:00
parent ce09c5ba0e
commit 6f4da18a55
2 changed files with 8 additions and 48 deletions

View File

@ -1,35 +1,27 @@
use lb_core::mantle::ops::channel::MsgId;
use lb_zone_sdk::sequencer::InscriptionInfo;
use crate::message::Msg;
/// Trait for the TUI's view of zone state.
/// Trait for the sequencer/indexer's view of zone state.
///
/// The TUI feeds SDK events into this trait; the trait owns persistence.
/// The sequencer/indexer feeds SDK events into this trait; the trait owns persistence.
/// `InMemoryZoneState` is the demo implementation. A real sequencer would
/// implement it over a DB so `published`/`adopted`/`finalized` survive
/// implement it over a DB so `published`/`finalized` survive
/// restarts (the SDK's own checkpoint covers tx-level resume separately).
///
/// Three lists, each ordered by arrival:
/// - `published`: our submissions, in submit order, until they finalize or get
/// orphaned.
/// - `adopted`: others' inscriptions on canonical, deduped by `msg_id` (reorgs
/// can re-adopt the same one), in first-sighting order.
/// - `finalized`: all inscriptions below LIB, in canonical order — the SDK
/// delivers `TxsFinalized`/`FinalizedInscriptions` per block.
///
/// Replay-idempotent: `on_adopted` and `on_finalized` dedup by `msg_id`, so
/// Replay-idempotent: `on_finalized` dedup by `msg_id`, so
/// resuming from a persisted state and re-receiving backfill is harmless.
pub trait ZoneState: Send {
fn on_published(&mut self, info: &InscriptionInfo);
fn on_adopted(&mut self, adopted: &[InscriptionInfo]);
/// Remove our orphaned entry from `published`. Caller is expected to
/// auto-republish via `handle.publish_message`.
fn on_orphaned(&mut self, msg_id: &MsgId);
fn on_finalized(&mut self, inscriptions: &[InscriptionInfo]);
fn published(&self) -> &[Msg];
fn adopted(&self) -> &[Msg];
fn finalized(&self) -> &[Msg];
}
@ -37,7 +29,6 @@ pub trait ZoneState: Send {
#[derive(Default)]
pub struct InMemoryZoneState {
published: Vec<Msg>,
adopted: Vec<Msg>,
finalized: Vec<Msg>,
}
@ -47,21 +38,6 @@ impl ZoneState for InMemoryZoneState {
.push(Msg::from_payload(info.this_msg, &info.payload));
}
fn on_adopted(&mut self, adopted: &[InscriptionInfo]) {
for info in adopted {
if !self.adopted.iter().any(|m| m.msg_id == info.this_msg) {
self.adopted
.push(Msg::from_payload(info.this_msg, &info.payload));
}
}
}
fn on_orphaned(&mut self, msg_id: &MsgId) {
if let Some(i) = self.published.iter().position(|m| &m.msg_id == msg_id) {
self.published.remove(i);
}
}
fn on_finalized(&mut self, inscriptions: &[InscriptionInfo]) {
for info in inscriptions {
if let Some(i) = self
@ -70,8 +46,6 @@ impl ZoneState for InMemoryZoneState {
.position(|m| m.msg_id == info.this_msg)
{
self.published.remove(i);
} else if let Some(i) = self.adopted.iter().position(|m| m.msg_id == info.this_msg) {
self.adopted.remove(i);
}
if !self.finalized.iter().any(|m| m.msg_id == info.this_msg) {
self.finalized
@ -84,10 +58,6 @@ impl ZoneState for InMemoryZoneState {
&self.published
}
fn adopted(&self) -> &[Msg] {
&self.adopted
}
fn finalized(&self) -> &[Msg] {
&self.finalized
}

View File

@ -14,7 +14,7 @@ use lb_core::mantle::ops::channel::{ChannelId, inscribe::Inscription};
use lb_key_management_system_service::keys::{ED25519_SECRET_KEY_SIZE, Ed25519Key};
use logos_blockchain_zone_sdk::{
adapter::NodeHttpClient,
sequencer::{Event, FinalizedOp, OrphanedTx, SequencerCheckpoint, SequencerClient, ZoneSequencer},
sequencer::{Event, FinalizedOp, SequencerCheckpoint, SequencerClient, ZoneSequencer},
};
use reqwest::Url;
use thiserror::Error;
@ -124,7 +124,7 @@ impl Sequencer {
tokio::spawn(async move {
// Wait until the sequencer completes cold-start backfill before publishing.
let mut ready_rx = batch_client.subscribe_ready();
let _ = ready_rx.wait_for(|r| *r).await;
drop(ready_rx.wait_for(|r| *r).await);
let mut interval = tokio::time::interval(Duration::from_millis(100));
loop {
@ -137,14 +137,13 @@ impl Sequencer {
loop {
let event = sequencer.next_event().await;
handle_event(event, &mut sequencer, &mut state, &checkpoint_path);
handle_event(event, &mut state, &checkpoint_path);
}
}
}
fn handle_event(
event: Event,
sequencer: &mut ZoneSequencer<NodeHttpClient>,
state: &mut InMemoryZoneState,
checkpoint_path: &str,
) {
@ -152,16 +151,7 @@ fn handle_event(
Event::Ready => {
info!("Sequencer ready");
}
Event::BlocksProcessed { checkpoint, channel_update, finalized } => {
state.on_adopted(&channel_update.adopted);
for orphan in &channel_update.orphaned {
let OrphanedTx::Inscription(info) = orphan else { continue };
state.on_orphaned(&info.this_msg);
debug!(msg_id = %hex::encode(info.this_msg.as_ref()), "Auto-republishing orphan");
if let Err(e) = sequencer.handle().publish(info.payload.clone()) {
error!("failed to auto-republish: {e}");
}
}
Event::BlocksProcessed { checkpoint, channel_update: _, finalized } => {
let inscriptions: Vec<_> = finalized
.into_iter()
.flat_map(|tx| tx.ops.into_iter())