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

  1. Speed up service query handlers: index reads, shrink per-query work, avoid recomputation
  2. Spread service-oracle queries across multiple blocks
  3. 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

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


AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22). Data as JSON: /api/errors/b6d1c7fb301d3a65. Report an issue: GitHub.