{"record":{"id":"b6d1c7fb301d3a65","repo":"linera-io/linera-protocol","slug":"maximumserviceoracleexecutiontimeexceeded","errorCode":"MaximumServiceOracleExecutionTimeExceeded","errorMessage":"ExecutionError::MaximumServiceOracleExecutionTimeExceeded","messagePattern":"ExecutionError::MaximumServiceOracleExecutionTimeExceeded","errorType":"exception","errorClass":"ExecutionError","httpStatus":null,"severity":"error","filePath":"linera-execution/src/resources.rs","lineNumber":802,"sourceCode":"            .as_mut()\n            .service_oracle_queries\n            .checked_add(1)\n            .ok_or(ArithmeticError::Overflow)?;\n        self.update_balance(self.policy.service_as_oracle_query)\n    }\n\n    /// Tracks the time spent executing the service as an oracle.\n    pub(crate) fn track_service_oracle_execution(\n        &mut self,\n        execution_time: Duration,\n    ) -> Result<(), ExecutionError> {\n        let tracker = self.tracker.as_mut();\n        let spent_execution_time = &mut tracker.service_oracle_execution;\n        let limit = Duration::from_millis(self.policy.maximum_service_oracle_execution_ms);\n\n        *spent_execution_time = spent_execution_time.saturating_add(execution_time);\n\n        ensure!(\n            *spent_execution_time < limit,\n            ExecutionError::MaximumServiceOracleExecutionTimeExceeded\n        );\n\n        Ok(())\n    }\n\n    /// Tracks the size of a response produced by an oracle.\n    pub(crate) fn track_service_oracle_response(\n        &self,\n        response_bytes: usize,\n    ) -> Result<(), ExecutionError> {\n        ensure!(\n            response_bytes as u64 <= self.policy.maximum_oracle_response_bytes,\n            ExecutionError::ServiceOracleResponseTooLarge\n        );\n\n        Ok(())","sourceCodeStart":784,"sourceCodeEnd":820,"githubUrl":"https://github.com/linera-io/linera-protocol/blob/6c226ddcb332ef55118dc8d0aafbd093d5420899/linera-execution/src/resources.rs#L784-L820","documentation":"track_service_oracle_execution accumulates the wall-clock time spent executing service-as-oracle queries within a block; once the cumulative time reaches maximum_service_oracle_execution_ms, tracking fails with MaximumServiceOracleExecutionTimeExceeded (resources.rs:802). The check is strict (<), so reaching exactly the limit also fails. This bounds how long a block may stall on service queries.","triggerScenarios":"A block performs several service-oracle queries and their combined execution time reaches the policy's maximum_service_oracle_execution_ms: slow handlers, many queries in one block, or a few very expensive ones.","commonSituations":"Service query handlers doing heavy reads or returning large data; too many oracle queries batched per block; dev machines slower than production timing assumptions; handlers that loop or wait internally.","solutions":["Speed up service query handlers: index reads, shrink per-query work, avoid recomputation","Spread service-oracle queries across multiple blocks","If you operate the network, raise maximum_service_oracle_execution_ms in the resource policy"],"exampleFix":"// before: heavy per-query work in the service handler\nfn handle_query(_: Query) -> Response { self.recompute_all_scores() }\n\n// after: precompute during operations, query only reads\nfn handle_operation(op: Op) { self.scores = self.compute(op); }\nfn handle_query(_: Query) -> Response { self.scores.clone() }","handlingStrategy":"fallback","validationCode":"// Client-side budgeting: keep per-block oracle query time under the policy cap\nlet limit = Duration::from_millis(policy.maximum_service_oracle_execution_ms);\nlet mut spent = Duration::ZERO;\nfor q in queries {\n    let est = estimated_query_time(&q);\n    if spent + est >= limit { break; } // defer remaining queries to the next block\n    spent += run_oracle_query(q).await?;\n}","typeGuard":"fn is_oracle_time_exceeded(err: &ExecutionError) -> bool {\n    matches!(err, ExecutionError::MaximumServiceOracleExecutionTimeExceeded)\n}","tryCatchPattern":"match block_builder.finalize().await {\n    Ok(b) => b,\n    Err(ref e) if is_oracle_time_exceeded(e) => {\n        // fallback: drop the slowest service-oracle queries from the block and re-propose\n        block_builder.drop_last_service_oracle_queries(1).await?;\n        block_builder.finalize().await\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Keep service query handlers fast; precompute during operations so queries only read","Budget the number of service-oracle queries per block against maximum_service_oracle_execution_ms","Time queries in tests so slow paths fail before they reach production blocks"],"tags":["service-oracle","execution-time","resource-limits","linera"],"backgroundTag":"execution-timeout","analyzedSha":"6c226ddcb332ef55118dc8d0aafbd093d5420899","analyzedAt":"2026-08-22T22:49:09.787Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}