linera-io/linera-protocol · error · ExecutionError
MaximumServiceOracleExecutionTimeExceeded
MaximumServiceOracleExecutionTimeExceeded
Error message
ExecutionError::MaximumServiceOracleExecutionTimeExceeded
What it means
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.
Source
Thrown at linera-execution/src/resources.rs:802
.as_mut()
.service_oracle_queries
.checked_add(1)
.ok_or(ArithmeticError::Overflow)?;
self.update_balance(self.policy.service_as_oracle_query)
}
/// Tracks the time spent executing the service as an oracle.
pub(crate) fn track_service_oracle_execution(
&mut self,
execution_time: Duration,
) -> Result<(), ExecutionError> {
let tracker = self.tracker.as_mut();
let spent_execution_time = &mut tracker.service_oracle_execution;
let limit = Duration::from_millis(self.policy.maximum_service_oracle_execution_ms);
*spent_execution_time = spent_execution_time.saturating_add(execution_time);
ensure!(
*spent_execution_time < limit,
ExecutionError::MaximumServiceOracleExecutionTimeExceeded
);
Ok(())
}
/// Tracks the size of a response produced by an oracle.
pub(crate) fn track_service_oracle_response(
&self,
response_bytes: usize,
) -> Result<(), ExecutionError> {
ensure!(
response_bytes as u64 <= self.policy.maximum_oracle_response_bytes,
ExecutionError::ServiceOracleResponseTooLarge
);
Ok(())View on GitHub (pinned to 6c226ddcb3)
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
Example fix
// before: heavy per-query work in the service handler
fn handle_query(_: Query) -> Response { self.recompute_all_scores() }
// after: precompute during operations, query only reads
fn handle_operation(op: Op) { self.scores = self.compute(op); }
fn handle_query(_: Query) -> Response { self.scores.clone() } Defensive patterns
Strategy: fallback
Validate before calling
// Client-side budgeting: keep per-block oracle query time under the policy cap
let limit = Duration::from_millis(policy.maximum_service_oracle_execution_ms);
let mut spent = Duration::ZERO;
for q in queries {
let est = estimated_query_time(&q);
if spent + est >= limit { break; } // defer remaining queries to the next block
spent += run_oracle_query(q).await?;
} Type guard
fn is_oracle_time_exceeded(err: &ExecutionError) -> bool {
matches!(err, ExecutionError::MaximumServiceOracleExecutionTimeExceeded)
} Try / catch
match block_builder.finalize().await {
Ok(b) => b,
Err(ref e) if is_oracle_time_exceeded(e) => {
// fallback: drop the slowest service-oracle queries from the block and re-propose
block_builder.drop_last_service_oracle_queries(1).await?;
block_builder.finalize().await
}
Err(e) => return Err(e.into()),
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- ServiceOracleResponseTooLarge
- Empty blocks are not allowed
- ServiceOracleQueryOperations
- MaximumFuelExceeded
- no signer found for owner ${owner}
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/b6d1c7fb301d3a65.
Report an issue: GitHub.