Skip to main content

iota_types/
metrics.rs

1// Copyright (c) Mysten Labs, Inc.
2// Modifications Copyright (c) 2024 IOTA Stiftung
3// SPDX-License-Identifier: Apache-2.0
4
5#[cfg(not(target_arch = "wasm32"))]
6use prometheus::{
7    Histogram, IntCounterVec, register_histogram_with_registry,
8    register_int_counter_vec_with_registry,
9};
10
11#[cfg(not(target_arch = "wasm32"))]
12pub struct LimitsMetrics {
13    /// Execution limits metrics
14    pub excessive_estimated_effects_size: IntCounterVec,
15    pub excessive_written_objects_size: IntCounterVec,
16    pub excessive_new_move_object_ids: IntCounterVec,
17    pub excessive_deleted_move_object_ids: IntCounterVec,
18    pub excessive_transferred_move_object_ids: IntCounterVec,
19    pub excessive_object_runtime_cached_objects: IntCounterVec,
20    pub excessive_object_runtime_store_entries: IntCounterVec,
21}
22
23#[cfg(not(target_arch = "wasm32"))]
24impl LimitsMetrics {
25    pub fn new(registry: &prometheus::Registry) -> LimitsMetrics {
26        Self {
27            excessive_estimated_effects_size: register_int_counter_vec_with_registry!(
28                "excessive_estimated_effects_size",
29                "Number of transactions with estimated effects size exceeding the limit",
30                &["metered", "limit_type"],
31                registry,
32            )
33                .unwrap(),
34            excessive_written_objects_size: register_int_counter_vec_with_registry!(
35                "excessive_written_objects_size",
36                "Number of transactions with written objects size exceeding the limit",
37                &["metered", "limit_type"],
38                registry,
39            )
40                .unwrap(),
41            excessive_new_move_object_ids: register_int_counter_vec_with_registry!(
42                "excessive_new_move_object_ids_size",
43                "Number of transactions with new move object ID count exceeding the limit",
44                &["metered", "limit_type"],
45                registry,
46            )
47                .unwrap(),
48            excessive_deleted_move_object_ids: register_int_counter_vec_with_registry!(
49                "excessive_deleted_move_object_ids_size",
50                "Number of transactions with deleted move object ID count exceeding the limit",
51                &["metered", "limit_type"],
52                registry,
53            )
54                .unwrap(),
55            excessive_transferred_move_object_ids: register_int_counter_vec_with_registry!(
56                "excessive_transferred_move_object_ids_size",
57                "Number of transactions with transferred move object ID count exceeding the limit",
58                &["metered", "limit_type"],
59                registry,
60            )
61                .unwrap(),
62            excessive_object_runtime_cached_objects: register_int_counter_vec_with_registry!(
63                "excessive_object_runtime_cached_objects_size",
64                "Number of transactions with object runtime cached object count exceeding the limit",
65                &["metered", "limit_type"],
66                registry,
67            )
68                .unwrap(),
69            excessive_object_runtime_store_entries: register_int_counter_vec_with_registry!(
70                "excessive_object_runtime_store_entries_size",
71                "Number of transactions with object runtime store entry count exceeding the limit",
72                &["metered", "limit_type"],
73                registry,
74            )
75                .unwrap(),
76        }
77    }
78}
79
80#[cfg(not(target_arch = "wasm32"))]
81pub struct BytecodeVerifierMetrics {
82    /// Bytecode verifier metrics timeout counter
83    pub verifier_timeout_metrics: IntCounterVec,
84    /// Bytecode verifier runtime latency for each module successfully verified
85    pub verifier_runtime_per_module_success_latency: Histogram,
86    /// Bytecode verifier runtime latency for each programmable transaction
87    /// block successfully verified
88    pub verifier_runtime_per_ptb_success_latency: Histogram,
89    /// Bytecode verifier runtime latency for each module which timed out
90    pub verifier_runtime_per_module_timeout_latency: Histogram,
91    /// Bytecode verifier runtime latency for each programmable transaction
92    /// block which timed out
93    pub verifier_runtime_per_ptb_timeout_latency: Histogram,
94}
95
96#[cfg(not(target_arch = "wasm32"))]
97impl BytecodeVerifierMetrics {
98    pub const OVERALL_TAG: &'static str = "overall";
99    pub const SUCCESS_TAG: &'static str = "success";
100    pub const TIMEOUT_TAG: &'static str = "failed";
101    const LATENCY_SEC_BUCKETS: &'static [f64] = &[
102        0.000_010, 0.000_025, 0.000_050, 0.000_100, // sub 100 nanos
103        0.000_250, 0.000_500, 0.001_000, 0.002_500, 0.005_000, 0.010_000, // sub 10 ms: p99
104        0.025_000, 0.050_000, 0.100_000, 0.250_000, 0.500_000, 1.000_000, // sub 1 s
105        10.000_000, 20.000_000, 50.000_000, 100.0, // We should almost never get here
106    ];
107    pub fn new(registry: &prometheus::Registry) -> Self {
108        Self {
109            verifier_timeout_metrics: register_int_counter_vec_with_registry!(
110                "verifier_timeout_metrics",
111                "Number of timeouts in bytecode verifier",
112                &["verifier_meter", "status"],
113                registry,
114            )
115            .unwrap(),
116            verifier_runtime_per_module_success_latency: register_histogram_with_registry!(
117                "verifier_runtime_per_module_success_latency",
118                "Time spent running bytecode verifier to completion at `run_metered_move_bytecode_verifier_impl`",
119                Self::LATENCY_SEC_BUCKETS.to_vec(),
120                registry
121            )
122            .unwrap(),
123            verifier_runtime_per_ptb_success_latency: register_histogram_with_registry!(
124                "verifier_runtime_per_ptb_success_latency",
125                "Time spent running bytecode verifier to completion over the entire PTB at `transaction_input_checker::check_non_system_packages_to_be_published`",
126                Self::LATENCY_SEC_BUCKETS.to_vec(),
127                registry
128            ).unwrap(),
129            verifier_runtime_per_module_timeout_latency:  register_histogram_with_registry!(
130                "verifier_runtime_per_module_timeout_latency",
131                "Time spent running bytecode verifier to timeout at `run_metered_move_bytecode_verifier_impl`",
132                Self::LATENCY_SEC_BUCKETS.to_vec(),
133                registry
134            )
135            .unwrap(),
136            verifier_runtime_per_ptb_timeout_latency: register_histogram_with_registry!(
137                "verifier_runtime_per_ptb_timeout_latency",
138                "Time spent running bytecode verifier to timeout over the entire PTB at `transaction_input_checker::check_non_system_packages_to_be_published`",
139                Self::LATENCY_SEC_BUCKETS.to_vec(),
140                registry
141            ).unwrap(),
142        }
143    }
144}
145
146// `prometheus` isn't available on wasm32; provide no-op stubs with a matching
147// API for the execution path. Constructed via `new_stub()` (no registry).
148#[cfg(target_arch = "wasm32")]
149mod wasm_stubs {
150    #[derive(Default, Clone)]
151    pub struct StubCounter;
152    impl StubCounter {
153        pub fn inc(&self) {}
154        pub fn inc_by(&self, _v: u64) {}
155    }
156
157    #[derive(Default, Clone)]
158    pub struct StubCounterVec;
159    impl StubCounterVec {
160        pub fn with_label_values(&self, _labels: &[&str]) -> StubCounter {
161            StubCounter
162        }
163    }
164
165    pub struct StubTimer;
166    impl StubTimer {
167        pub fn observe_duration(self) {}
168        pub fn stop_and_record(self) -> f64 {
169            0.0
170        }
171        pub fn stop_and_discard(self) -> f64 {
172            0.0
173        }
174    }
175
176    #[derive(Default, Clone)]
177    pub struct StubHistogram;
178    impl StubHistogram {
179        pub fn observe(&self, _v: f64) {}
180        pub fn start_timer(&self) -> StubTimer {
181            StubTimer
182        }
183    }
184
185    pub struct LimitsMetrics {
186        pub excessive_estimated_effects_size: StubCounterVec,
187        pub excessive_written_objects_size: StubCounterVec,
188        pub excessive_new_move_object_ids: StubCounterVec,
189        pub excessive_deleted_move_object_ids: StubCounterVec,
190        pub excessive_transferred_move_object_ids: StubCounterVec,
191        pub excessive_object_runtime_cached_objects: StubCounterVec,
192        pub excessive_object_runtime_store_entries: StubCounterVec,
193    }
194
195    impl LimitsMetrics {
196        pub fn new_stub() -> Self {
197            Self {
198                excessive_estimated_effects_size: StubCounterVec,
199                excessive_written_objects_size: StubCounterVec,
200                excessive_new_move_object_ids: StubCounterVec,
201                excessive_deleted_move_object_ids: StubCounterVec,
202                excessive_transferred_move_object_ids: StubCounterVec,
203                excessive_object_runtime_cached_objects: StubCounterVec,
204                excessive_object_runtime_store_entries: StubCounterVec,
205            }
206        }
207    }
208
209    pub struct BytecodeVerifierMetrics {
210        pub verifier_timeout_metrics: StubCounterVec,
211        pub verifier_runtime_per_module_success_latency: StubHistogram,
212        pub verifier_runtime_per_ptb_success_latency: StubHistogram,
213        pub verifier_runtime_per_module_timeout_latency: StubHistogram,
214        pub verifier_runtime_per_ptb_timeout_latency: StubHistogram,
215    }
216
217    impl BytecodeVerifierMetrics {
218        pub const OVERALL_TAG: &'static str = "overall";
219        pub const SUCCESS_TAG: &'static str = "success";
220        pub const TIMEOUT_TAG: &'static str = "failed";
221
222        pub fn new_stub() -> Self {
223            Self {
224                verifier_timeout_metrics: StubCounterVec,
225                verifier_runtime_per_module_success_latency: StubHistogram,
226                verifier_runtime_per_ptb_success_latency: StubHistogram,
227                verifier_runtime_per_module_timeout_latency: StubHistogram,
228                verifier_runtime_per_ptb_timeout_latency: StubHistogram,
229            }
230        }
231    }
232}
233
234#[cfg(target_arch = "wasm32")]
235pub use wasm_stubs::*;