diff --git a/Cargo.lock b/Cargo.lock index 3f973541..9c5eb98c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8953,8 +8953,10 @@ name = "sequencer_service_protocol" version = "0.1.0" dependencies = [ "common", + "hex", "lee", "lee_core", + "serde_with", ] [[package]] diff --git a/lez/sequencer/core/src/block_publisher.rs b/lez/sequencer/core/src/block_publisher.rs index ab2cbf86..21551131 100644 --- a/lez/sequencer/core/src/block_publisher.rs +++ b/lez/sequencer/core/src/block_publisher.rs @@ -4,7 +4,7 @@ use anyhow::{Context as _, Result, anyhow}; use common::block::Block; use log::{info, warn}; pub use logos_blockchain_core::mantle::ops::channel::MsgId; -use logos_blockchain_core::mantle::ops::channel::inscribe::Inscription; +use logos_blockchain_core::mantle::ops::channel::{ChannelId, inscribe::Inscription}; pub use logos_blockchain_key_management_system_service::keys::{Ed25519Key, ZkKey}; pub use logos_blockchain_zone_sdk::sequencer::SequencerCheckpoint; use logos_blockchain_zone_sdk::{ @@ -61,11 +61,14 @@ pub trait BlockPublisherTrait: Clone { /// Fire-and-forget publish. Zone-sdk drives the actual submission and /// retries internally; this just hands the payload off. async fn publish_block(&self, block: &Block, withdrawals: Vec) -> Result<()>; + + fn channel_id(&self) -> ChannelId; } /// Real block publisher backed by zone-sdk's `ZoneSequencer`. #[derive(Clone)] pub struct ZoneSdkPublisher { + channel_id: ChannelId, publish_tx: mpsc::Sender<(Inscription, Vec)>, // Aborts the drive task when the last clone is dropped. _drive_task: Arc, @@ -192,6 +195,7 @@ impl BlockPublisherTrait for ZoneSdkPublisher { .context("Zone-sdk readiness channel closed before becoming ready")?; Ok(Self { + channel_id: config.channel_id, publish_tx, _drive_task: Arc::new(DriveTaskGuard(drive_task)), }) @@ -210,6 +214,10 @@ impl BlockPublisherTrait for ZoneSdkPublisher { Ok(()) } + + fn channel_id(&self) -> ChannelId { + self.channel_id + } } /// Deserialize inscription payload as a `Block` and return it's`block_id`. diff --git a/lez/sequencer/core/src/mock.rs b/lez/sequencer/core/src/mock.rs index 5f2ab8cf..39f635f9 100644 --- a/lez/sequencer/core/src/mock.rs +++ b/lez/sequencer/core/src/mock.rs @@ -2,6 +2,7 @@ use std::time::Duration; use anyhow::Result; use common::block::Block; +use logos_blockchain_core::mantle::ops::channel::ChannelId; use logos_blockchain_key_management_system_service::keys::Ed25519Key; use logos_blockchain_zone_sdk::sequencer::WithdrawArg; @@ -16,11 +17,13 @@ use crate::{ pub type SequencerCoreWithMockClients = crate::SequencerCore; #[derive(Clone)] -pub struct MockBlockPublisher; +pub struct MockBlockPublisher { + channel_id: ChannelId, +} impl BlockPublisherTrait for MockBlockPublisher { async fn new( - _config: &BedrockConfig, + config: &BedrockConfig, _bedrock_signing_key: Ed25519Key, _resubmit_interval: Duration, _initial_checkpoint: Option, @@ -29,7 +32,9 @@ impl BlockPublisherTrait for MockBlockPublisher { _on_deposit_event: OnDepositEventSink, _on_withdraw_event: OnWithdrawEventSink, ) -> Result { - Ok(Self) + Ok(Self { + channel_id: config.channel_id, + }) } async fn publish_block( @@ -39,4 +44,8 @@ impl BlockPublisherTrait for MockBlockPublisher { ) -> Result<()> { Ok(()) } + + fn channel_id(&self) -> ChannelId { + self.channel_id + } } diff --git a/lez/sequencer/service/protocol/Cargo.toml b/lez/sequencer/service/protocol/Cargo.toml index 06d51c88..ced19e75 100644 --- a/lez/sequencer/service/protocol/Cargo.toml +++ b/lez/sequencer/service/protocol/Cargo.toml @@ -11,3 +11,6 @@ workspace = true common.workspace = true lee.workspace = true lee_core.workspace = true + +hex.workspace = true +serde_with.workspace = true diff --git a/lez/sequencer/service/protocol/src/lib.rs b/lez/sequencer/service/protocol/src/lib.rs index a8863997..58e300f6 100644 --- a/lez/sequencer/service/protocol/src/lib.rs +++ b/lez/sequencer/service/protocol/src/lib.rs @@ -1,5 +1,28 @@ //! Reexports of types used by sequencer rpc specification. +use std::{fmt::Display, str::FromStr}; + pub use common::{HashType, block::Block, transaction::LeeTransaction}; pub use lee::{Account, AccountId, ProgramId}; pub use lee_core::{BlockId, Commitment, MembershipProof, account::Nonce}; +use serde_with::{DeserializeFromStr, SerializeDisplay}; + +#[derive(Debug, Clone, PartialEq, Eq, Hash, SerializeDisplay, DeserializeFromStr)] +pub struct ChannelId(pub [u8; 32]); + +impl Display for ChannelId { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let hex_string = hex::encode(self.0); + write!(f, "{hex_string}") + } +} + +impl FromStr for ChannelId { + type Err = hex::FromHexError; + + fn from_str(s: &str) -> Result { + let mut bytes = [0_u8; 32]; + hex::decode_to_slice(s, &mut bytes)?; + Ok(Self(bytes)) + } +} diff --git a/lez/sequencer/service/rpc/src/lib.rs b/lez/sequencer/service/rpc/src/lib.rs index 2cc85d7d..914232c0 100644 --- a/lez/sequencer/service/rpc/src/lib.rs +++ b/lez/sequencer/service/rpc/src/lib.rs @@ -6,8 +6,8 @@ use jsonrpsee::types::ErrorObjectOwned; #[cfg(feature = "client")] pub use jsonrpsee::{core::ClientError, http_client::HttpClientBuilder as SequencerClientBuilder}; use sequencer_service_protocol::{ - Account, AccountId, Block, BlockId, Commitment, HashType, LeeTransaction, MembershipProof, - Nonce, ProgramId, + Account, AccountId, Block, BlockId, ChannelId, Commitment, HashType, LeeTransaction, + MembershipProof, Nonce, ProgramId, }; #[cfg(all(not(feature = "server"), not(feature = "client")))] @@ -88,5 +88,8 @@ pub trait Rpc { #[method(name = "getProgramIds")] async fn get_program_ids(&self) -> Result, ErrorObjectOwned>; + #[method(name = "getChannelId")] + async fn get_channel_id(&self) -> Result; + // ============================================================================================= } diff --git a/lez/sequencer/service/src/service.rs b/lez/sequencer/service/src/service.rs index f3d791dc..3a48e7cc 100644 --- a/lez/sequencer/service/src/service.rs +++ b/lez/sequencer/service/src/service.rs @@ -12,7 +12,8 @@ use sequencer_core::{ DbError, SequencerCore, TransactionOrigin, block_publisher::BlockPublisherTrait, }; use sequencer_service_protocol::{ - Account, AccountId, Block, BlockId, Commitment, HashType, MembershipProof, Nonce, ProgramId, + Account, AccountId, Block, BlockId, ChannelId, Commitment, HashType, MembershipProof, Nonce, + ProgramId, }; use tokio::sync::Mutex; @@ -176,6 +177,11 @@ impl sequencer_service_rpc::RpcServer ); Ok(program_ids) } + + async fn get_channel_id(&self) -> Result { + let channel_id = self.sequencer.lock().await.block_publisher().channel_id(); + Ok(ChannelId(*channel_id.as_ref())) + } } fn internal_error(err: &DbError) -> ErrorObjectOwned {