diff --git a/crates/katana/node/src/lib.rs b/crates/katana/node/src/lib.rs index 31003668ee..da93752473 100644 --- a/crates/katana/node/src/lib.rs +++ b/crates/katana/node/src/lib.rs @@ -32,7 +32,6 @@ use katana_executor::implementation::blockifier::BlockifierFactory; use katana_executor::{ExecutionFlags, ExecutorFactory}; use katana_pipeline::stage::Sequencing; use katana_pool::ordering::FiFo; -use katana_pool::validation::stateful::TxValidator; use katana_pool::TxPool; use katana_primitives::block::GasPrices; use katana_primitives::env::{CfgEnv, FeeTokenAddressses}; @@ -119,7 +118,6 @@ impl Node { let pool = self.pool.clone(); let backend = self.backend.clone(); let block_producer = self.block_producer.clone(); - let validator = self.block_producer.validator().clone(); // --- build and run sequencing task @@ -138,7 +136,7 @@ impl Node { .name("Sequencing") .spawn(sequencing.into_future()); - let node_components = (pool, backend, block_producer, validator, self.forked_client.take()); + let node_components = (pool, backend, block_producer, self.forked_client.take()); let rpc = spawn(node_components, self.config.rpc.clone()).await?; Ok(LaunchedNode { node: self, rpc }) @@ -250,16 +248,10 @@ pub async fn build(mut config: Config) -> Result { // Moved from `katana_rpc` crate pub async fn spawn( - node_components: ( - TxPool, - Arc>, - BlockProducer, - TxValidator, - Option, - ), + node_components: (TxPool, Arc>, BlockProducer, Option), config: RpcConfig, ) -> Result { - let (pool, backend, block_producer, validator, forked_client) = node_components; + let (pool, backend, block_producer, forked_client) = node_components; let mut methods = RpcModule::new(()); methods.register_method("health", |_, _| Ok(serde_json::json!({ "health": true })))?; @@ -272,12 +264,11 @@ pub async fn spawn( backend.clone(), pool.clone(), block_producer.clone(), - validator, client, cfg, ) } else { - StarknetApi::new(backend.clone(), pool.clone(), block_producer.clone(), validator, cfg) + StarknetApi::new(backend.clone(), pool.clone(), Some(block_producer.clone()), cfg) }; methods.merge(StarknetApiServer::into_rpc(server.clone()))?; diff --git a/crates/katana/rpc/rpc/src/starknet/config.rs b/crates/katana/rpc/rpc/src/starknet/config.rs new file mode 100644 index 0000000000..dd61cca524 --- /dev/null +++ b/crates/katana/rpc/rpc/src/starknet/config.rs @@ -0,0 +1,7 @@ +#[derive(Debug, Clone)] +pub struct StarknetApiConfig { + /// The max chunk size that can be served from the `getEvents` method. + /// + /// If `None`, the maximum chunk size is bounded by [`u64::MAX`]. + pub max_event_page_size: Option, +} diff --git a/crates/katana/rpc/rpc/src/starknet/mod.rs b/crates/katana/rpc/rpc/src/starknet/mod.rs index c17cb790c3..c0d4256987 100644 --- a/crates/katana/rpc/rpc/src/starknet/mod.rs +++ b/crates/katana/rpc/rpc/src/starknet/mod.rs @@ -1,17 +1,10 @@ //! Server implementation for the Starknet JSON-RPC API. -pub mod forking; -mod read; -mod trace; -mod write; - use std::sync::Arc; -use forking::ForkedClient; use katana_core::backend::Backend; use katana_core::service::block_producer::{BlockProducer, BlockProducerMode, PendingExecutor}; use katana_executor::{ExecutionResult, ExecutorFactory}; -use katana_pool::validation::stateful::TxValidator; use katana_pool::{TransactionPool, TxPool}; use katana_primitives::block::{ BlockHash, BlockHashOrNumber, BlockIdOrTag, BlockNumber, BlockTag, FinalityStatus, @@ -51,75 +44,85 @@ use starknet::core::types::{ use crate::utils; use crate::utils::events::{Cursor, EventBlockId}; -pub type StarknetApiResult = Result; +mod config; +pub mod forking; +mod read; +mod trace; +mod write; -#[allow(missing_debug_implementations)] -pub struct StarknetApi { - inner: Arc>, -} +pub use config::StarknetApiConfig; +use forking::ForkedClient; -#[derive(Debug, Clone)] -pub struct StarknetApiConfig { - pub max_event_page_size: Option, -} +type StarknetApiResult = Result; -impl Clone for StarknetApi { - fn clone(&self) -> Self { - Self { inner: Arc::clone(&self.inner) } - } +/// Handler for the Starknet JSON-RPC server. +/// +/// This struct implements all the JSON-RPC traits required to serve the Starknet API (ie, +/// [read](katana_rpc_api::starknet::StarknetApi), +/// [write](katana_rpc_api::starknet::StarknetWriteApi), and +/// [trace](katana_rpc_api::starknet::StarknetTraceApi) APIs. +#[allow(missing_debug_implementations)] +pub struct StarknetApi +where + EF: ExecutorFactory, +{ + inner: Arc>, } -struct Inner { - validator: TxValidator, +struct StarknetApiInner +where + EF: ExecutorFactory, +{ pool: TxPool, backend: Arc>, - block_producer: BlockProducer, - blocking_task_pool: BlockingTaskPool, forked_client: Option, + blocking_task_pool: BlockingTaskPool, + block_producer: Option>, config: StarknetApiConfig, } -impl StarknetApi { +impl StarknetApi +where + EF: ExecutorFactory, +{ pub fn new( backend: Arc>, pool: TxPool, - block_producer: BlockProducer, - validator: TxValidator, + block_producer: Option>, config: StarknetApiConfig, ) -> Self { - Self::new_inner(backend, pool, block_producer, validator, None, config) + Self::new_inner(backend, pool, block_producer, None, config) } pub fn new_forked( backend: Arc>, pool: TxPool, block_producer: BlockProducer, - validator: TxValidator, forked_client: ForkedClient, config: StarknetApiConfig, ) -> Self { - Self::new_inner(backend, pool, block_producer, validator, Some(forked_client), config) + Self::new_inner(backend, pool, Some(block_producer), Some(forked_client), config) } fn new_inner( backend: Arc>, pool: TxPool, - block_producer: BlockProducer, - validator: TxValidator, + block_producer: Option>, forked_client: Option, config: StarknetApiConfig, ) -> Self { let blocking_task_pool = BlockingTaskPool::new().expect("failed to create blocking task pool"); - let inner = Inner { + + let inner = StarknetApiInner { pool, backend, block_producer, blocking_task_pool, - validator, forked_client, config, }; + Self { inner: Arc::new(inner) } } @@ -184,10 +187,10 @@ impl StarknetApi { /// Returns the pending state if the sequencer is running in _interval_ mode. Otherwise `None`. fn pending_executor(&self) -> Option { - match &*self.inner.block_producer.producer.read() { + self.inner.block_producer.as_ref().and_then(|bp| match &*bp.producer.read() { BlockProducerMode::Instant(_) => None, BlockProducerMode::Interval(producer) => Some(producer.executor()), - } + }) } fn state(&self, block_id: &BlockIdOrTag) -> StarknetApiResult> { @@ -357,7 +360,7 @@ impl StarknetApi { // TODO: this is a temporary solution, we should have a better way to handle this. // perhaps a pending/pool state provider that implements all the state provider traits. let result = if let BlockIdOrTag::Tag(BlockTag::Pending) = block_id { - this.inner.validator.pool_nonce(contract_address)? + this.inner.pool.validator().pool_nonce(contract_address)? } else { let state = this.state(&block_id)?; state.nonce(contract_address)? @@ -1122,3 +1125,12 @@ impl StarknetApi { Ok(id) } } + +impl Clone for StarknetApi +where + EF: ExecutorFactory, +{ + fn clone(&self) -> Self { + Self { inner: Arc::clone(&self.inner) } + } +}