Skip to main content

2.3 Canister state

Intermediate
Tutorial

Globally mutable state refers to data that exists across your entire program, is accessible from anywhere, and can be changed during runtime.

On ICP, canisters are designed in a way that naturally encourages the use of globally mutable state. However, Rust's language design discourages or restricts global mutable variables, which means Rust developers need to adopt code organization strategies that align with ICP's architecture while respecting Rust's safety principles. One of these strategies is using thread_local! with Cell/RefCell for state variables.

Globally mutable state typically requires thread safety. However, the RefCell type in Rust is not thread-safe by default. To safely use RefCell for global mutable state, you can wrap it inside a thread_local! variable. Since thread_local! creates data local to each thread, it does not require thread safety, allowing safe mutation without synchronization overhead.

thread_local! {
    static NEXT_USER_ID: Cell<u64> = Cell::new(0);
    static ACTIVE_USERS: RefCell<UserMap> = RefCell::new(UserMap::new());
}

It's recommended to organize most of your canister's code into loosely coupled modules and packages that can be tested independently. Code that directly interacts with the system API should generally reside in the main file.

Additionally, you can create a thin abstraction layer over the system API to facilitate testing. For example, you might define a trait to abstract the stable memory API like this:

pub trait Memory {
    fn size(&self) -> WasmPages;
    fn grow(&self, pages: WasmPages) -> WasmPages;
    fn read(&self, offset: u32, dst: &mut [u8]);
    fn write(&self, offset: u32, src: &[u8]);
}
ICP AstronautNeed help?

Did you get stuck somewhere in this tutorial, or do you feel like you need additional help understanding some of the concepts? The ICP community has several resources available for developers, like working groups and bootcamps, along with our Discord community, forum, and events such as hackathons. Here are a few to check out: