diff --git a/crates/katana/cli/src/args.rs b/crates/katana/cli/src/args.rs index ce2efcb01e..1ff1c3ce36 100644 --- a/crates/katana/cli/src/args.rs +++ b/crates/katana/cli/src/args.rs @@ -238,6 +238,7 @@ impl NodeArgs { cors_origins: self.server.http_cors_origins.clone(), max_event_page_size: Some(self.server.max_event_page_size), max_proof_keys: Some(self.server.max_proof_keys), + max_call_gas: Some(self.server.max_call_gas), }) } diff --git a/crates/katana/cli/src/options.rs b/crates/katana/cli/src/options.rs index bfd93cfaf8..3daaa51cdd 100644 --- a/crates/katana/cli/src/options.rs +++ b/crates/katana/cli/src/options.rs @@ -18,7 +18,7 @@ use katana_node::config::metrics::{DEFAULT_METRICS_ADDR, DEFAULT_METRICS_PORT}; use katana_node::config::rpc::{RpcModulesList, DEFAULT_RPC_MAX_PROOF_KEYS}; #[cfg(feature = "server")] use katana_node::config::rpc::{ - DEFAULT_RPC_ADDR, DEFAULT_RPC_MAX_EVENT_PAGE_SIZE, DEFAULT_RPC_PORT, + DEFAULT_RPC_ADDR, DEFAULT_RPC_MAX_CALL_GAS, DEFAULT_RPC_MAX_EVENT_PAGE_SIZE, DEFAULT_RPC_PORT, }; use katana_primitives::block::BlockHashOrNumber; use katana_primitives::chain::ChainId; @@ -128,6 +128,12 @@ pub struct ServerOptions { #[arg(default_value_t = DEFAULT_RPC_MAX_PROOF_KEYS)] #[serde(default = "default_proof_keys")] pub max_proof_keys: u64, + + /// Maximum gas for the `starknet_call` RPC method. + #[arg(long = "rpc.max-call-gas", value_name = "GAS")] + #[arg(default_value_t = DEFAULT_RPC_MAX_CALL_GAS)] + #[serde(default = "default_max_call_gas")] + pub max_call_gas: u64, } #[cfg(feature = "server")] @@ -143,6 +149,7 @@ impl Default for ServerOptions { max_connections: None, max_request_body_size: None, max_response_body_size: None, + max_call_gas: DEFAULT_RPC_MAX_CALL_GAS, } } } @@ -410,3 +417,8 @@ fn default_metrics_addr() -> IpAddr { fn default_metrics_port() -> u16 { DEFAULT_METRICS_PORT } + +#[cfg(feature = "server")] +fn default_max_call_gas() -> u64 { + DEFAULT_RPC_MAX_CALL_GAS +} diff --git a/crates/katana/executor/src/implementation/blockifier/mod.rs b/crates/katana/executor/src/implementation/blockifier/mod.rs index ee38b16cdf..319a5199a5 100644 --- a/crates/katana/executor/src/implementation/blockifier/mod.rs +++ b/crates/katana/executor/src/implementation/blockifier/mod.rs @@ -44,12 +44,17 @@ pub struct BlockifierFactory { cfg: CfgEnv, flags: ExecutionFlags, limits: BlockLimits, + max_call_gas: u64, } impl BlockifierFactory { /// Create a new factory with the given configuration and simulation flags. pub fn new(cfg: CfgEnv, flags: ExecutionFlags, limits: BlockLimits) -> Self { - Self { cfg, flags, limits } + Self { cfg, flags, limits, max_call_gas: 1_000_000_000 } + } + + pub fn set_max_call_gas(&mut self, max_call_gas: u64) { + self.max_call_gas = max_call_gas; } } @@ -72,7 +77,14 @@ impl ExecutorFactory for BlockifierFactory { let cfg_env = self.cfg.clone(); let flags = self.flags.clone(); let limits = self.limits.clone(); - Box::new(StarknetVMProcessor::new(Box::new(state), block_env, cfg_env, flags, limits)) + Box::new(StarknetVMProcessor::new( + Box::new(state), + block_env, + cfg_env, + flags, + limits, + self.max_call_gas, + )) } fn cfg(&self) -> &CfgEnv { @@ -93,6 +105,7 @@ pub struct StarknetVMProcessor<'a> { simulation_flags: ExecutionFlags, stats: ExecutionStats, bouncer: Bouncer, + max_call_gas: u64, } impl<'a> StarknetVMProcessor<'a> { @@ -102,6 +115,7 @@ impl<'a> StarknetVMProcessor<'a> { cfg_env: CfgEnv, simulation_flags: ExecutionFlags, limits: BlockLimits, + max_call_gas: u64, ) -> Self { let transactions = Vec::new(); let block_context = utils::block_context_from_envs(&block_env, &cfg_env); @@ -118,6 +132,7 @@ impl<'a> StarknetVMProcessor<'a> { simulation_flags, stats: Default::default(), bouncer, + max_call_gas, } } @@ -329,7 +344,7 @@ impl ExecutorExt for StarknetVMProcessor<'_> { let block_context = &self.block_context; let mut state = self.state.inner.lock(); let state = MutRefState::new(&mut state.cached_state); - let retdata = call::execute_call(call, state, block_context, 1_000_000_000)?; + let retdata = call::execute_call(call, state, block_context, self.max_call_gas)?; Ok(retdata) } } diff --git a/crates/katana/node-bindings/src/lib.rs b/crates/katana/node-bindings/src/lib.rs index dec102f63b..bdcca9c275 100644 --- a/crates/katana/node-bindings/src/lib.rs +++ b/crates/katana/node-bindings/src/lib.rs @@ -188,6 +188,7 @@ pub struct Katana { http_addr: Option, http_port: Option, rpc_max_connections: Option, + rpc_max_call_gas: Option, http_cors_domain: Option, // Dev options @@ -326,6 +327,12 @@ impl Katana { self } + /// Sets the maximum gas for the `starknet_call` RPC method. + pub const fn rpc_max_call_gas(mut self, max_call_gas: u64) -> Self { + self.rpc_max_call_gas = Some(max_call_gas); + self + } + /// Enables the CORS layer and sets the allowed origins, separated by commas. pub fn http_cors_domain>(mut self, allowed_origins: T) -> Self { self.http_cors_domain = Some(allowed_origins.into()); @@ -525,6 +532,10 @@ impl Katana { cmd.arg("--rpc.max-connections").arg(max_connections.to_string()); } + if let Some(max_call_gas) = self.rpc_max_call_gas { + cmd.arg("--rpc.max-call-gas").arg(max_call_gas.to_string()); + } + if let Some(allowed_origins) = self.http_cors_domain { cmd.arg("--http.corsdomain").arg(allowed_origins); } diff --git a/crates/katana/node/src/config/rpc.rs b/crates/katana/node/src/config/rpc.rs index 7d31c8db6e..57d5c63212 100644 --- a/crates/katana/node/src/config/rpc.rs +++ b/crates/katana/node/src/config/rpc.rs @@ -11,6 +11,8 @@ pub const DEFAULT_RPC_PORT: u16 = 5050; pub const DEFAULT_RPC_MAX_EVENT_PAGE_SIZE: u64 = 1024; /// Default maximmum number of keys for the `starknet_getStorageProof` RPC method. pub const DEFAULT_RPC_MAX_PROOF_KEYS: u64 = 100; +/// Default maximum gas for the `starknet_call` RPC method. +pub const DEFAULT_RPC_MAX_CALL_GAS: u64 = 1_000_000_000; /// List of RPC modules supported by Katana. #[derive( @@ -45,6 +47,7 @@ pub struct RpcConfig { pub max_response_body_size: Option, pub max_proof_keys: Option, pub max_event_page_size: Option, + pub max_call_gas: Option, } impl RpcConfig { @@ -66,6 +69,7 @@ impl Default for RpcConfig { apis: RpcModulesList::default(), max_event_page_size: Some(DEFAULT_RPC_MAX_EVENT_PAGE_SIZE), max_proof_keys: Some(DEFAULT_RPC_MAX_PROOF_KEYS), + max_call_gas: Some(DEFAULT_RPC_MAX_CALL_GAS), } } } diff --git a/crates/katana/node/src/lib.rs b/crates/katana/node/src/lib.rs index 83772a5ff3..5ec25cce61 100644 --- a/crates/katana/node/src/lib.rs +++ b/crates/katana/node/src/lib.rs @@ -182,11 +182,16 @@ pub async fn build(mut config: Config) -> Result { .with_account_validation(config.dev.account_validation) .with_fee(config.dev.fee); - let executor_factory = Arc::new(BlockifierFactory::new( - cfg_env, - execution_flags, - config.sequencing.block_limits(), - )); + let executor_factory = { + let mut factory = + BlockifierFactory::new(cfg_env, execution_flags, config.sequencing.block_limits()); + + if let Some(max_call_gas) = config.rpc.max_call_gas { + factory.set_max_call_gas(max_call_gas); + } + + Arc::new(factory) + }; // --- build backend