diff --git a/.prettierignore b/.prettierignore index b1ace5fd1..425efec96 100644 --- a/.prettierignore +++ b/.prettierignore @@ -14,3 +14,8 @@ orchestrator/build/ orchestrator/node_modules/ lib/ s3/ + +*.rs +*.toml +Cargo.toml +Cargo.lock diff --git a/madara/crates/client/db/src/lib.rs b/madara/crates/client/db/src/lib.rs index dd75a07df..0f6c5a59b 100644 --- a/madara/crates/client/db/src/lib.rs +++ b/madara/crates/client/db/src/lib.rs @@ -392,21 +392,6 @@ impl MadaraBackend { Ok(()) } - pub fn get_custom_header(&self) -> Option { - self.get_custom_header_with_clear(false) - } - - pub fn get_custom_header_with_clear(&self, clear: bool) -> Option { - let mut guard = self.custom_header.lock().expect("Poisoned lock"); - let result = guard.clone(); - - if clear { - *guard = None; - } - - result - } - pub fn set_custom_header(&self, custom_header: CustomHeader) { let mut guard = self.custom_header.lock().expect("Poisoned lock"); *guard = Some(custom_header); @@ -495,6 +480,21 @@ impl MadaraBackend { pub fn chain_config(&self) -> &Arc { &self.chain_config } + + pub fn get_custom_header(&self) -> Option { + self.get_custom_header_with_clear(false) + } + + pub fn get_custom_header_with_clear(&self, clear: bool) -> Option { + let mut guard = self.custom_header.lock().expect("Poisoned lock"); + let result = guard.clone(); + + if clear { + *guard = None; + } + + result + } } /// Structure holding exclusive access to write the blocks and the tip of the chain. diff --git a/madara/crates/client/exec/src/layered_state_adapter.rs b/madara/crates/client/exec/src/layered_state_adapter.rs index 328b456ea..cbc32b64b 100644 --- a/madara/crates/client/exec/src/layered_state_adapter.rs +++ b/madara/crates/client/exec/src/layered_state_adapter.rs @@ -45,18 +45,22 @@ impl LayeredStateAdapter { let view = backend.view_on_latest_confirmed(); let block_number = view.latest_block_n().map(|n| n + 1).unwrap_or(/* genesis */ 0); - let l1_gas_quote = backend - .get_last_l1_gas_quote() - .context("No L1 gas quote available. Ensure that the L1 gas quote is set before calculating gas prices.")?; - - let gas_prices = if let Some(block) = view.block_view_on_latest_confirmed() { - let block_info = block.get_block_info()?; - let previous_strk_l2_gas_price = block_info.header.gas_prices.strk_l2_gas_price; - let previous_l2_gas_used = block_info.total_l2_gas_used; - - backend.calculate_gas_prices(&l1_gas_quote, previous_strk_l2_gas_price, previous_l2_gas_used)? + let gas_prices = if let Some(custom_header) = backend.get_custom_header().filter(|h| h.block_n == block_number) { + custom_header.gas_prices } else { - backend.calculate_gas_prices(&l1_gas_quote, 0, 0)? + let l1_gas_quote = backend + .get_last_l1_gas_quote() + .context("No L1 gas quote available. Ensure that the L1 gas quote is set before calculating gas prices.")?; + + if let Some(block) = view.block_view_on_latest_confirmed() { + let block_info = block.get_block_info()?; + let previous_strk_l2_gas_price = block_info.header.gas_prices.strk_l2_gas_price; + let previous_l2_gas_used = block_info.total_l2_gas_used; + + backend.calculate_gas_prices(&l1_gas_quote, previous_strk_l2_gas_price, previous_l2_gas_used)? + } else { + backend.calculate_gas_prices(&l1_gas_quote, 0, 0)? + } }; Ok(Self { diff --git a/madara/crates/client/rpc/src/versions/admin/v0_1_0/methods/write.rs b/madara/crates/client/rpc/src/versions/admin/v0_1_0/methods/write.rs index 3673e0bff..2b6a7bfee 100644 --- a/madara/crates/client/rpc/src/versions/admin/v0_1_0/methods/write.rs +++ b/madara/crates/client/rpc/src/versions/admin/v0_1_0/methods/write.rs @@ -11,7 +11,8 @@ use mp_rpc::v0_9_0::{ ClassAndTxnHash, ContractAndTxnHash, }; use mp_transactions::{L1HandlerTransactionResult, L1HandlerTransactionWithFee}; - +use mp_utils::service::{MadaraServiceId, MadaraServiceStatus}; +use std::time::Duration; #[async_trait] impl MadaraWriteRpcApiV0_1_0Server for Starknet { /// Submit a new class v0 declaration transaction, bypassing mempool and all validation. @@ -126,7 +127,26 @@ impl MadaraWriteRpcApiV0_1_0Server for Starknet { } } + // Check if block production is currently running (sequencer mode) + let bp_was_running = matches!( + self.ctx.service_status(MadaraServiceId::BlockProduction), + MadaraServiceStatus::On + ); + + // If running, shut down block production cleanly before reorg + if bp_was_running { + tracing::info!("🔌 Stopping block production service for reorg..."); + self.ctx.service_remove(MadaraServiceId::BlockProduction); + // Allow time for clean shutdown of executor threads and channels + tokio::time::sleep(Duration::from_millis(100)).await; + tracing::info!("✅ Block production service stopped"); + } + + // Perform the blockchain reorg + tracing::info!("🔄 Reverting blockchain to block {}", target_block_n); self.backend.revert_to(&block_hash).map_err(StarknetRpcApiError::from)?; + + // Update chain tip cache let fresh_chain_tip = self .backend .db @@ -135,6 +155,15 @@ impl MadaraWriteRpcApiV0_1_0Server for Starknet { .map_err(StarknetRpcApiError::from)?; let backend_chain_tip = mc_db::ChainTip::from_storage(fresh_chain_tip); self.backend.chain_tip.send_replace(backend_chain_tip); + tracing::info!("✅ Blockchain reverted successfully"); + + // Restart block production if it was running before + if bp_was_running { + tracing::info!("🔌 Restarting block production service after reorg..."); + self.ctx.service_add(MadaraServiceId::BlockProduction); + tracing::info!("✅ Block production service restarted with fresh state"); + } + Ok(()) }