rialo-types 0.2.0-alpha.0

Rialo Types
Documentation
// Copyright (c) Subzero Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

use rialo_limits::max_oracle_output_serialized_bytes;
use serde_derive::{Deserialize, Serialize};

use crate::{OracleInfo, TimestampMs, WebSocketOperation};

/// Configuration for oracle duties.
///
/// This struct defines the parameters that control how oracle duties are scheduled,
/// executed, and finalized within the system.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct OracleDutyConfig {
    /// The number of validators assigned to each oracle duty.
    pub validators_per_duty: u32,
    /// The time in milliseconds to wait before an oracle request is issued.
    pub oracle_request_delay_ms: TimestampMs,
    /// Max size of oracle output in bytes.
    pub max_oracle_output_size: u32,
    /// Optionally, change the compute usage limit.
    pub compute_units_limit: Option<u32>,
    /// Optionally, change the heap size limit.
    pub heap_size_limit: Option<u32>,
    /// Whether this duty is ASAP (execute as soon as possible) rather than scheduled.
    pub is_asap: bool,
    /// WebSocket operation information needed to update the WebSocketRegistry with the
    /// on-chain connection state when this duty completes.
    pub websocket_op: Option<WebSocketOperation>,
}

impl Default for OracleDutyConfig {
    fn default() -> Self {
        Self {
            // 3-validator committees gives us 99.996% success rate leveraging TEE guarantees
            validators_per_duty: Self::DEFAULT_VALIDATORS_PER_DUTY,
            // Time to execute an oracle, determined experimentally
            oracle_request_delay_ms: Self::DEFAULT_ORACLE_REQUEST_DELAY_MS,
            // Safe size for the default number of validators.
            max_oracle_output_size: Self::DEFAULT_MAX_ORACLE_OUTPUT_SIZE,
            compute_units_limit: None,
            heap_size_limit: None,
            is_asap: false,
            websocket_op: None,
        }
    }
}

impl OracleDutyConfig {
    /// Constructs an instance based on OracleInfo.
    pub fn from_oracle_info(oracle_info: &OracleInfo) -> Self {
        Self {
            validators_per_duty: oracle_info.validators_per_duty,
            oracle_request_delay_ms: oracle_info.oracle_request_delay_ms,
            max_oracle_output_size: max_oracle_output_serialized_bytes(
                oracle_info.validators_per_duty,
            ) as u32,
            compute_units_limit: oracle_info.compute_units_limit,
            heap_size_limit: oracle_info.heap_size_limit,
            is_asap: oracle_info.is_asap(),
            websocket_op: oracle_info.websocket_op(),
        }
    }

    /// Safe max size limit for the default number of validators.
    pub const DEFAULT_MAX_ORACLE_OUTPUT_SIZE: u32 = 10 * 1024;

    /// A reasonably safe value to make one-off oracles succeed with >22 bits of security.
    /// This value is based on the example from the Rialo whitepaper, that is N = 130, D = 43.
    pub const ONE_OFF_VALIDATORS_PER_DUTY: u32 = 13;

    /// A small value for oracles that is reasonably cheap.
    /// Note that by itself it doesn't provide a response reliably enough
    /// and needs retries in case of failure.
    pub const DEFAULT_VALIDATORS_PER_DUTY: u32 = 5;

    /// Most oracles should complete within a few blocks.
    pub const DEFAULT_ORACLE_REQUEST_DELAY_MS: TimestampMs = 300; // 0.3s

    /// The minimum allowed delay for oracle requests, in milliseconds.
    pub const MIN_ORACLE_REQUEST_DELAY: TimestampMs = 100; // 0.1s

    /// The maximum allowed delay for oracle requests, in milliseconds.
    pub const MAX_ORACLE_REQUEST_DELAY_MS: TimestampMs = 240_000; // 240s

    /// Default maximum number of ASAP duties to process in a single consensus round
    pub const DEFAULT_MAX_ASAP_DUTIES_PER_COMMIT: usize = 5;

    /// Default timeout for ASAP duties in milliseconds
    pub const DEFAULT_ASAP_TIMEOUT_MS: TimestampMs = 5_000; // 5s

    /// Sets the oracle request delay (in milliseconds).
    ///
    /// # Arguments
    ///
    /// * `delay` - The time in milliseconds to wait before issuing an oracle request.
    pub fn set_oracle_request_delay_ms(mut self, delay: TimestampMs) -> Self {
        self.oracle_request_delay_ms = delay;
        self
    }

    /// Sets the desired number of validators per duty.
    pub fn set_validators_per_duty(mut self, validators_per_duty: u32) -> OracleDutyConfig {
        self.validators_per_duty = validators_per_duty;
        self
    }
}