1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// 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
}
}