DEV Community

Harshed Abdulla
Harshed Abdulla

Posted on

Stable Memory In Internet Computer

Stable memory refers to a type of memory on the Internet Computer (IC) that allows data to persist across canister (smart contract) upgrades.

It’s a memory type that retains its state even when the canister is upgraded or restarted, ensuring that critical data is not lost during these operations. This is useful for applications that need to maintain state across different versions of their smart contracts.

Difference Between Stable Memory and Heap Memory:

  1. Stable Memory:

• Persistence: Data stored in stable memory survives canister upgrades and restarts.
• Scope: It is used to store data that must persist beyond temporary computations (such as database records, user preferences, or any other data that should remain constant).
• Size Limitations: 500 GiB.

  1. Heap Memory:

• Persistence: Data stored in heap memory is volatile and will be lost when the canister is restarted or upgraded.

• Scope: It is used for temporary storage during computations.
• Size Limitations: Heap memory is more flexible and can be used for larger datasets that don’t need to persist across upgrades.

How Data is Stored in IC:

Data on the Internet Computer is stored within canisters (smart contracts), and this data can be divided into:

  1. Stable Memory: Retains state across canister upgrades.
  2. Heap Memory: Used for temporary, non-persistent storage during computations.

Data Persistence:
Data persistence refers to the ability of data to remain available even after the application (or the environment) that created it has stopped or undergone changes. In the context of IC, this is achieved using stable memory, which ensures data stays intact even after upgrades or restarts of canisters.

How to Implement Stable Memory in IC in Rust:

use ic_stable_structures::memory_manager::{MemoryId, MemoryManager, VirtualMemory};
use ic_stable_structures::{DefaultMemoryImpl, StableBTreeMap};
use std::cell::RefCell;

// defines a type alias for virtual memory implementation that uses default stable memory backend.
type Memory = VirtualMemory<DefaultMemoryImpl>;

// ensures that the variables are thread local to maintain concurrency.
thread_local! {
    // memory manager is used to manage multiple instances of stable memory.
    static MEMORY_MANAGER: RefCell<MemoryManager<DefaultMemoryImpl>> =
        RefCell::new(MemoryManager::init(DefaultMemoryImpl::default()));

    // key value optimized for stability and efficiency.
    static MAP: RefCell<StableBTreeMap<u128, u128, Memory>> = RefCell::new(
        StableBTreeMap::init(
            MEMORY_MANAGER.with(|m| m.borrow().get(MemoryId::new(0))),
        )
    );
}

// retrives the value associated with the key.
#[ic_cdk::query]
fn get(key: u128) -> Option<u128> {
    MAP.with(|p| p.borrow().get(&key))
}

// inserts a key value pair into the map.
#[ic_cdk::update]
fn insert(key: u128, value: u128) -> Option<u128> {
    MAP.with(|p| p.borrow_mut().insert(key, value))
}


Enter fullscreen mode Exit fullscreen mode

Code Explanation

  1. Memory Type Definition:
    • type Memory = VirtualMemory: Defines a memory type for stable storage using the default backend.

  2. Thread-Local Storage:
    • thread_local!: Ensures safe, thread-local access to stable memory and the StableBTreeMap.

  3. Stable Memory Manager:
    • MEMORY_MANAGER: Manages stable memory regions and provides access using MemoryId.

  4. Stable Key-Value Store:
    • MAP: A StableBTreeMap optimized for persisting key-value pairs.

  5. Query and Update Methods:
    • get: A read-only query to retrieve the value for a given key.
    • insert: An update method to add or modify a key-value pair.

Conclusion

Stable memory is a powerful feature of the Internet Computer, enabling developers to build resilient, data-persistent applications. By leveraging tools like ic-stable-structures, developers can create scalable and efficient systems that ensure data integrity across canister upgrades. Understanding the differences between stable memory and heap memory is crucial for optimizing application design and performance.

By implementing the techniques discussed in this article, you can ensure that your IC applications are not only robust but also future-proof. 🚀

Top comments (0)