ic_cdk/api.rs
1//! System API bindings.
2//!
3//! This module provides Rust ergonomic bindings to the system APIs.
4//!
5//! Some APIs require more advanced handling and are organized into separate modules:
6//! * For the inter-canister calls API, see the [`call`](mod@crate::call) module.
7//! * For the stable memory management API, see the .
8//! * The basic bindings are provided in this module including [`stable_size`], [`stable_grow`], [`stable_read`] and [`stable_write`].
9//! * The [`stable`](crate::stable) module provides more advanced functionalities, e.g. support for `std::io` traits.
10//!
11//! APIs that are only available for `wasm32` are not included.
12//! As a result, system APIs with a numeric postfix (indicating the data bit width) are bound to names without the postfix.
13//! For example, `ic0::msg_cycles_available128` is bound to [`msg_cycles_available`], while `ic0::msg_cycles_available` has no binding.
14//!
15//! Functions that provide bindings for a single system API method share the same name as the system API.
16//! For example, `ic0::msg_reject_code` is bound to [`msg_reject_code`].
17//!
18//! Functions that wrap multiple system API methods are named using the common prefix of the wrapped methods.
19//! For example, [`msg_arg_data`] wraps both `ic0::msg_arg_data_size` and `ic0::msg_arg_data_copy`.
20
21use candid::Principal;
22use std::{convert::TryFrom, num::NonZeroU64};
23
24#[deprecated(
25 since = "0.18.0",
26 note = "The `api::call` module is deprecated. Individual items within this module have their own deprecation notices with specific migration guidance."
27)]
28pub mod call;
29#[deprecated(
30 since = "0.18.0",
31 note = "The `api::management_canister` module is deprecated. Please use the `management_canister` and `bitcoin_canister` modules at the crate root."
32)]
33pub mod management_canister;
34#[deprecated(
35 since = "0.18.0",
36 note = "The `api::stable` module has been moved to `stable` (crate root)."
37)]
38pub mod stable;
39
40/// Gets the message argument data.
41pub fn msg_arg_data() -> Vec<u8> {
42 let len = ic0::msg_arg_data_size();
43 let mut buf = vec![0u8; len];
44 ic0::msg_arg_data_copy(&mut buf, 0);
45 buf
46}
47
48/// Gets the identity of the caller, which may be a canister id or a user id.
49///
50/// During canister installation or upgrade, this is the id of the user or canister requesting the installation or upgrade.
51/// During a system task (heartbeat or global timer), this is the id of the management canister.
52pub fn msg_caller() -> Principal {
53 let len = ic0::msg_caller_size();
54 let mut buf = vec![0u8; len];
55 ic0::msg_caller_copy(&mut buf, 0);
56 // Trust that the system always returns a valid principal.
57 Principal::try_from(&buf).unwrap()
58}
59
60/// Returns the reject code, if the current function is invoked as a reject callback.
61pub fn msg_reject_code() -> u32 {
62 ic0::msg_reject_code()
63}
64
65/// Gets the reject message.
66///
67/// This function can only be called in the reject callback.
68///
69/// Traps if there is no reject message (i.e. if `reject_code` is 0).
70pub fn msg_reject_msg() -> String {
71 let len = ic0::msg_reject_msg_size();
72 let mut buf = vec![0u8; len];
73 ic0::msg_reject_msg_copy(&mut buf, 0);
74 String::from_utf8_lossy(&buf).into_owned()
75}
76
77/// Gets the deadline, in nanoseconds since 1970-01-01, after which the caller might stop waiting for a response.
78///
79/// For calls to update methods with best-effort responses and their callbacks,
80/// the deadline is computed based on the time the call was made,
81/// and the `timeout_seconds` parameter provided by the caller.
82/// In such cases, the deadline value will be converted to `NonZeroU64` and wrapped in `Some`.
83/// To get the deadline value as a `u64`, call `get()` on the `NonZeroU64` value.
84///
85/// ```rust,no_run
86/// use ic_cdk::api::msg_deadline;
87/// if let Some(deadline) = msg_deadline() {
88/// let deadline_value : u64 = deadline.get();
89/// }
90/// ```
91///
92/// For other calls (ingress messages and all calls to query and composite query methods,
93/// including calls in replicated mode), a `None` is returned.
94/// Please note that the raw `msg_deadline` system API returns 0 in such cases.
95/// This function is a wrapper around the raw system API that provides more semantic information through the return type.
96pub fn msg_deadline() -> Option<NonZeroU64> {
97 let nano_seconds = ic0::msg_deadline();
98 match nano_seconds {
99 0 => None,
100 _ => Some(NonZeroU64::new(nano_seconds).unwrap()),
101 }
102}
103
104/// Replies to the sender with the data.
105pub fn msg_reply<T: AsRef<[u8]>>(data: T) {
106 let buf = data.as_ref();
107 if !buf.is_empty() {
108 ic0::msg_reply_data_append(buf);
109 }
110 ic0::msg_reply();
111}
112
113/// Rejects the call with a diagnostic message.
114pub fn msg_reject<T: AsRef<str>>(message: T) {
115 let message = message.as_ref();
116 ic0::msg_reject(message.as_bytes());
117}
118
119/// Gets the number of cycles transferred by the caller of the current call, still available in this message.
120pub fn msg_cycles_available() -> u128 {
121 ic0::msg_cycles_available128()
122}
123
124/// Gets the amount of cycles that came back with the response as a refund
125///
126/// This function can only be used in a callback handler (reply or reject).
127/// The refund has already been added to the canister balance automatically.
128pub fn msg_cycles_refunded() -> u128 {
129 ic0::msg_cycles_refunded128()
130}
131
132/// Moves cycles from the call to the canister balance.
133///
134/// The actual amount moved will be returned.
135pub fn msg_cycles_accept(max_amount: u128) -> u128 {
136 ic0::msg_cycles_accept128(max_amount)
137}
138
139/// Burns cycles from the canister.
140///
141/// Returns the amount of cycles that were actually burned.
142pub fn cycles_burn(amount: u128) -> u128 {
143 ic0::cycles_burn128(amount)
144}
145
146/// Gets canister's own identity.
147pub fn canister_self() -> Principal {
148 let len = ic0::canister_self_size();
149 let mut buf = vec![0u8; len];
150 ic0::canister_self_copy(&mut buf, 0);
151 // Trust that the system always returns a valid principal.
152 Principal::try_from(&buf).unwrap()
153}
154
155/// Gets the current cycle balance of the canister.
156pub fn canister_cycle_balance() -> u128 {
157 ic0::canister_cycle_balance128()
158}
159
160/// Gets the current amount of cycles that is available for spending in calls and execution.
161pub fn canister_liquid_cycle_balance() -> u128 {
162 ic0::canister_liquid_cycle_balance128()
163}
164
165/// Gets the status of the canister.
166///
167/// The status is one of the following:
168///.- 1: Running
169///.- 2: Stopping
170///.- 3: Stopped
171pub fn canister_status() -> CanisterStatusCode {
172 ic0::canister_status().into()
173}
174
175/// The status of a canister.
176///
177/// See [Canister status](https://internetcomputer.org/docs/current/references/ic-interface-spec/#system-api-canister-status).
178#[derive(Debug, PartialEq, Eq, Clone, Copy)]
179#[repr(u32)]
180pub enum CanisterStatusCode {
181 /// Running.
182 Running = 1,
183 /// Stopping.
184 Stopping = 2,
185 /// Stopped.
186 Stopped = 3,
187 /// A status code that is not recognized by this library.
188 Unrecognized(u32),
189}
190
191impl From<u32> for CanisterStatusCode {
192 fn from(value: u32) -> Self {
193 match value {
194 1 => Self::Running,
195 2 => Self::Stopping,
196 3 => Self::Stopped,
197 _ => Self::Unrecognized(value),
198 }
199 }
200}
201
202impl From<CanisterStatusCode> for u32 {
203 fn from(value: CanisterStatusCode) -> Self {
204 match value {
205 CanisterStatusCode::Running => 1,
206 CanisterStatusCode::Stopping => 2,
207 CanisterStatusCode::Stopped => 3,
208 CanisterStatusCode::Unrecognized(value) => value,
209 }
210 }
211}
212
213impl PartialEq<u32> for CanisterStatusCode {
214 fn eq(&self, other: &u32) -> bool {
215 let self_as_u32: u32 = (*self).into();
216 self_as_u32 == *other
217 }
218}
219
220/// Gets the canister version.
221///
222/// See [Canister version](https://internetcomputer.org/docs/current/references/ic-interface-spec/#system-api-canister-version).
223pub fn canister_version() -> u64 {
224 ic0::canister_version()
225}
226
227/// Gets the ID of the subnet on which the canister is running.
228pub fn subnet_self() -> Principal {
229 let len = ic0::subnet_self_size();
230 let mut buf = vec![0u8; len];
231 ic0::subnet_self_copy(&mut buf, 0);
232 // Trust that the system always returns a valid principal.
233 Principal::try_from(&buf).unwrap()
234}
235
236/// Gets the name of the method to be inspected.
237///
238/// This function is only available in the `canister_inspect_message` context.
239pub fn msg_method_name() -> String {
240 let len = ic0::msg_method_name_size();
241 let mut buf = vec![0u8; len];
242 ic0::msg_method_name_copy(&mut buf, 0);
243 String::from_utf8_lossy(&buf).into_owned()
244}
245
246/// Accepts the message in `canister_inspect_message`.
247///
248/// This function is only available in the `canister_inspect_message` context.
249/// This function traps if invoked twice.
250pub fn accept_message() {
251 ic0::accept_message();
252}
253
254/// Gets the current size of the stable memory (in WebAssembly pages).
255///
256/// One WebAssembly page is 64KiB.
257pub fn stable_size() -> u64 {
258 ic0::stable64_size()
259}
260
261/// Attempts to grow the stable memory by `new_pages` many pages containing zeroes.
262///
263/// One WebAssembly page is 64KiB.
264///
265/// If successful, returns the previous size of the memory (in pages).
266/// Otherwise, returns `u64::MAX`.
267pub fn stable_grow(new_pages: u64) -> u64 {
268 ic0::stable64_grow(new_pages)
269}
270
271/// Writes data to the stable memory location specified by an offset.
272///
273/// # Warning
274/// This will panic if `offset + buf.len()` exceeds the current size of stable memory.
275/// Call [`stable_grow`] to request more stable memory if needed.
276pub fn stable_write(offset: u64, buf: &[u8]) {
277 ic0::stable64_write(buf, offset);
278}
279
280/// Reads data from the stable memory location specified by an offset.
281///
282/// # Warning
283/// This will panic if `offset + buf.len()` exceeds the current size of stable memory.
284pub fn stable_read(offset: u64, buf: &mut [u8]) {
285 ic0::stable64_read(buf, offset);
286}
287
288/// Gets the public key (a DER-encoded BLS key) of the root key of this instance of the Internet Computer Protocol.
289///
290/// # Note
291///
292/// This traps in non-replicated mode.
293pub fn root_key() -> Vec<u8> {
294 let len = ic0::root_key_size();
295 let mut buf = vec![0u8; len];
296 ic0::root_key_copy(&mut buf, 0);
297 buf
298}
299
300/// Sets the certified data of this canister.
301///
302/// Canisters can store up to 32 bytes of data that is certified by
303/// the system on a regular basis. One can call [`data_certificate`]
304/// function from a query call to get a certificate authenticating the
305/// value set by calling this function.
306///
307/// This function can only be called from the following contexts:
308/// - `canister_init`, `canister_pre_upgrade` and `canister_post_upgrade`
309/// hooks.
310/// - `canister_update` calls.
311/// - reply or reject callbacks.
312///
313/// # Panics
314///
315/// - This function traps if `data.len() > 32`.
316/// - This function traps if it's called from an illegal context
317/// (e.g., from a query call).
318pub fn certified_data_set<T: AsRef<[u8]>>(data: T) {
319 let buf = data.as_ref();
320 ic0::certified_data_set(buf);
321}
322
323/// When called from a query call, returns the data certificate authenticating
324/// certified data set by this canister.
325///
326/// Returns `None` if called not from a query call.
327pub fn data_certificate() -> Option<Vec<u8>> {
328 if ic0::data_certificate_present() == 0 {
329 return None;
330 }
331 let n = ic0::data_certificate_size();
332 let mut buf = vec![0u8; n];
333 ic0::data_certificate_copy(&mut buf, 0);
334 Some(buf)
335}
336
337/// Gets current timestamp, in nanoseconds since the epoch (1970-01-01)
338pub fn time() -> u64 {
339 ic0::time()
340}
341
342/// Sets global timer.
343///
344/// The canister can set a global timer to make the system
345/// schedule a call to the exported `canister_global_timer`
346/// Wasm method after the specified time.
347/// The time must be provided as nanoseconds since 1970-01-01.
348///
349/// The function returns the previous value of the timer.
350/// If no timer is set before invoking the function, then the function returns zero.
351///
352/// Passing zero as an argument to the function deactivates the timer and thus
353/// prevents the system from scheduling calls to the canister's `canister_global_timer` Wasm method.
354pub fn global_timer_set(timestamp: u64) -> u64 {
355 ic0::global_timer_set(timestamp)
356}
357
358/// Gets the value of specified performance counter.
359///
360/// See [`PerformanceCounterType`] for available counter types.
361#[inline]
362pub fn performance_counter(counter_type: impl Into<PerformanceCounterType>) -> u64 {
363 let counter_type: u32 = counter_type.into().into();
364 ic0::performance_counter(counter_type)
365}
366
367/// The type of performance counter.
368#[derive(Debug, PartialEq, Eq, Clone, Copy)]
369#[repr(u32)]
370pub enum PerformanceCounterType {
371 /// Current execution instruction counter.
372 ///
373 /// The number of WebAssembly instructions the canister has executed
374 /// since the beginning of the current Message execution.
375 InstructionCounter,
376 /// Call context instruction counter
377 ///
378 /// The number of WebAssembly instructions the canister has executed
379 /// within the call context of the current Message execution
380 /// since Call context creation.
381 /// The counter monotonically increases across all message executions
382 /// in the call context until the corresponding call context is removed.
383 CallContextInstructionCounter,
384 /// A performance counter type that is not recognized by this library.
385 Unrecognized(u32),
386}
387
388impl From<u32> for PerformanceCounterType {
389 fn from(value: u32) -> Self {
390 match value {
391 0 => Self::InstructionCounter,
392 1 => Self::CallContextInstructionCounter,
393 _ => Self::Unrecognized(value),
394 }
395 }
396}
397
398impl From<PerformanceCounterType> for u32 {
399 fn from(value: PerformanceCounterType) -> Self {
400 match value {
401 PerformanceCounterType::InstructionCounter => 0,
402 PerformanceCounterType::CallContextInstructionCounter => 1,
403 PerformanceCounterType::Unrecognized(value) => value,
404 }
405 }
406}
407
408impl PartialEq<u32> for PerformanceCounterType {
409 fn eq(&self, other: &u32) -> bool {
410 let self_as_u32: u32 = (*self).into();
411 self_as_u32 == *other
412 }
413}
414
415/// Returns the number of instructions that the canister executed since the last [entry
416/// point](https://internetcomputer.org/docs/current/references/ic-interface-spec/#entry-points).
417#[inline]
418pub fn instruction_counter() -> u64 {
419 performance_counter(0)
420}
421
422/// Returns the number of WebAssembly instructions the canister has executed
423/// within the call context of the current Message execution since
424/// Call context creation.
425///
426/// The counter monotonically increases across all message executions
427/// in the call context until the corresponding call context is removed.
428#[inline]
429pub fn call_context_instruction_counter() -> u64 {
430 performance_counter(1)
431}
432
433/// Determines if a Principal is a controller of the canister.
434pub fn is_controller(principal: &Principal) -> bool {
435 let slice = principal.as_slice();
436 ic0::is_controller(slice) != 0
437}
438
439/// Checks if in replicated execution.
440///
441/// The canister can check whether it is currently running in replicated or non replicated execution.
442pub fn in_replicated_execution() -> bool {
443 match ic0::in_replicated_execution() {
444 0 => false,
445 1 => true,
446 _ => panic!("unexpected return value from in_replicated_execution"),
447 }
448}
449
450/// Gets the amount of cycles that a canister needs to be above the freezing threshold in order to successfully make an inter-canister call.
451pub fn cost_call(method_name_size: u64, payload_size: u64) -> u128 {
452 ic0::cost_call(method_name_size, payload_size)
453}
454
455/// Gets the cycle cost of the Management canister method [`creating_canister`](https://internetcomputer.org/docs/references/ic-interface-spec#ic-create_canister).
456///
457/// # Note
458///
459/// [`create_canister`](crate::management_canister::create_canister) and
460/// [`create_canister_with_extra_cycles`](crate::management_canister::create_canister_with_extra_cycles)
461/// invoke this function inside and attach the required cycles to the call.
462pub fn cost_create_canister() -> u128 {
463 ic0::cost_create_canister()
464}
465
466/// Gets the cycle cost of the Management canister method [`http_request`](https://internetcomputer.org/docs/references/ic-interface-spec#ic-http_request).
467///
468/// # Note
469///
470/// [`http_request`](crate::management_canister::http_request) and [`http_request_with_closure`](crate::management_canister::http_request_with_closure)
471/// invoke this function inside and attach the required cycles to the call.
472pub fn cost_http_request(request_size: u64, max_res_bytes: u64) -> u128 {
473 ic0::cost_http_request(request_size, max_res_bytes)
474}
475
476/// The error type for [`cost_sign_with_ecdsa`] and [`cost_sign_with_schnorr`].
477#[derive(thiserror::Error, Debug, Clone)]
478pub enum SignCostError {
479 /// The ECDSA/vetKD curve or Schnorr algorithm is invalid.
480 #[error("invalid curve or algorithm")]
481 InvalidCurveOrAlgorithm,
482
483 /// The key name is invalid for the provided curve or algorithm.
484 #[error("invalid key name")]
485 InvalidKeyName,
486 /// Unrecognized error.
487 ///
488 /// This error is returned when the System API returns an unrecognized error code.
489 /// Please report to ic-cdk maintainers.
490 #[error("unrecognized error: {0}")]
491 UnrecognizedError(u32),
492}
493
494/// Helper function to handle the result of a signature cost function.
495fn sign_cost_result(dst: u128, code: u32) -> Result<u128, SignCostError> {
496 match code {
497 0 => Ok(dst),
498 1 => Err(SignCostError::InvalidCurveOrAlgorithm),
499 2 => Err(SignCostError::InvalidKeyName),
500 _ => Err(SignCostError::UnrecognizedError(code)),
501 }
502}
503
504/// Gets the cycle cost of the Management canister method [`sign_with_ecdsa`](https://internetcomputer.org/docs/references/ic-interface-spec#ic-sign_with_ecdsa).
505///
506/// # Note
507///
508/// Alternatively, [`management_canister::cost_sign_with_ecdsa`](crate::management_canister::cost_sign_with_ecdsa) provides a higher-level API that wraps this function.
509///
510/// # Errors
511///
512/// This function will return an error if the `key_name` or the `ecdsa_curve` is invalid.
513/// The error type [`SignCostError`] provides more information about the reason of the error.
514pub fn cost_sign_with_ecdsa<T: AsRef<str>>(
515 key_name: T,
516 ecdsa_curve: u32,
517) -> Result<u128, SignCostError> {
518 let key_name = key_name.as_ref();
519 let (cost, code) = ic0::cost_sign_with_ecdsa(key_name, ecdsa_curve);
520 sign_cost_result(cost, code)
521}
522
523/// Gets the cycle cost of the Management canister method [`sign_with_schnorr`](https://internetcomputer.org/docs/references/ic-interface-spec#ic-sign_with_schnorr).
524///
525/// # Note
526///
527/// Alternatively, [`management_canister::cost_sign_with_schnorr`](crate::management_canister::cost_sign_with_schnorr) provides a higher-level API that wraps this function.
528///
529/// # Errors
530///
531/// This function will return an error if the `key_name` or the `algorithm` is invalid.
532/// The error type [`SignCostError`] provides more information about the reason of the error.
533pub fn cost_sign_with_schnorr<T: AsRef<str>>(
534 key_name: T,
535 algorithm: u32,
536) -> Result<u128, SignCostError> {
537 let key_name = key_name.as_ref();
538 let (dst, code) = ic0::cost_sign_with_schnorr(key_name, algorithm);
539 sign_cost_result(dst, code)
540}
541
542/// Gets the cycle cost of the Management canister method [`vetkd_derive_key`](https://github.com/dfinity/portal/pull/3763).
543///
544/// Later, the description will be available in [the interface spec](https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-vetkd_derive_key).
545///
546/// # Note
547///
548/// Alternatively, [`management_canister::cost_vetkd_derive_key`](crate::management_canister::cost_vetkd_derive_key) provides a higher-level API that wraps this function.
549///
550/// # Errors
551///
552/// This function will return an error if the `key_name` or the `vetkd_curve` is invalid.
553/// The error type [`SignCostError`] provides more information about the reason of the error.
554pub fn cost_vetkd_derive_key<T: AsRef<str>>(
555 key_name: T,
556 vetkd_curve: u32,
557) -> Result<u128, SignCostError> {
558 let key_name = key_name.as_ref();
559 let (cost, code) = ic0::cost_vetkd_derive_key(key_name, vetkd_curve);
560 sign_cost_result(cost, code)
561}
562
563/// Emits textual trace messages.
564///
565/// On the "real" network, these do not do anything.
566///
567/// When executing in an environment that supports debugging, this copies out the data
568/// and logs, prints or stores it in an environment-appropriate way.
569pub fn debug_print<T: AsRef<str>>(data: T) {
570 let buf = data.as_ref();
571 ic0::debug_print(buf.as_bytes());
572}
573
574/// Traps with the given message.
575///
576/// The environment may copy out the data and log, print or store it in an environment-appropriate way,
577/// or include it in system-generated reject messages where appropriate.
578pub fn trap<T: AsRef<str>>(data: T) -> ! {
579 let buf = data.as_ref();
580 ic0::trap(buf.as_bytes());
581}
582
583// # Deprecated API bindings
584//
585// The following functions are deprecated and will be removed in the future.
586// They are kept here for compatibility with existing code.
587
588/// Prints the given message.
589#[deprecated(since = "0.18.0", note = "Use `debug_print` instead")]
590pub fn print<S: std::convert::AsRef<str>>(s: S) {
591 let s = s.as_ref();
592 ic0::debug_print(s.as_bytes());
593}
594
595/// Returns the caller of the current call.
596#[deprecated(since = "0.18.0", note = "Use `msg_caller` instead")]
597pub fn caller() -> Principal {
598 let len = ic0::msg_caller_size();
599 let mut bytes = vec![0u8; len];
600 ic0::msg_caller_copy(&mut bytes, 0);
601 Principal::try_from(&bytes).unwrap()
602}
603
604/// Returns the canister id as a blob.
605#[deprecated(since = "0.18.0", note = "Use `canister_self` instead")]
606pub fn id() -> Principal {
607 let len = ic0::canister_self_size();
608 let mut bytes = vec![0u8; len];
609 ic0::canister_self_copy(&mut bytes, 0);
610 Principal::try_from(&bytes).unwrap()
611}
612
613/// Gets the amount of funds available in the canister.
614///
615/// # Panic
616///
617/// When the cycle balance is greater than `u64::MAX`, this function will panic.
618/// As this function is deprecated, it is recommended to use [`canister_cycle_balance`].
619#[deprecated(since = "0.18.0", note = "Use `canister_cycle_balance` instead")]
620pub fn canister_balance() -> u64 {
621 // ic0 no longer provides `ic0.canister_cycle_balance` which returns a u64,
622 // so we use the u128 version and convert it to u64.
623 // When the cycle balance is greater than `u64::MAX`, `ic0.canister_cycle_balance` also panics.
624 canister_cycle_balance()
625 .try_into()
626 .expect("the cycle balance is greater than u64::MAX, please use canister_cycle_balance which returns u128")
627}
628
629/// Gets the amount of funds available in the canister.
630#[deprecated(since = "0.18.0", note = "Use `canister_cycle_balance` instead")]
631pub fn canister_balance128() -> u128 {
632 canister_cycle_balance()
633}
634
635/// Sets the certified data of this canister.
636///
637/// Canisters can store up to 32 bytes of data that is certified by
638/// the system on a regular basis. One can call [`data_certificate`]
639/// function from a query call to get a certificate authenticating the
640/// value set by calling this function.
641///
642/// This function can only be called from the following contexts:
643/// - `canister_init`, `canister_pre_upgrade` and `canister_post_upgrade`
644/// hooks.
645/// - `canister_update` calls.
646/// - reply or reject callbacks.
647///
648/// # Panics
649///
650/// - This function traps if `data.len() > 32`.
651/// - This function traps if it's called from an illegal context
652/// (e.g., from a query call).
653#[deprecated(since = "0.18.0", note = "Use `certified_data_set` instead")]
654pub fn set_certified_data(data: &[u8]) {
655 ic0::certified_data_set(data);
656}
657
658/// Sets global timer.
659///
660/// The canister can set a global timer to make the system
661/// schedule a call to the exported `canister_global_timer`
662/// Wasm method after the specified time.
663/// The time must be provided as nanoseconds since 1970-01-01.
664///
665/// The function returns the previous value of the timer.
666/// If no timer is set before invoking the function, then the function returns zero.
667///
668/// Passing zero as an argument to the function deactivates the timer and thus
669/// prevents the system from scheduling calls to the canister's `canister_global_timer` Wasm method.
670#[deprecated(since = "0.18.0", note = "Use `global_timer_set` instead")]
671pub fn set_global_timer(timestamp: u64) -> u64 {
672 ic0::global_timer_set(timestamp)
673}