Containers
SnapshotItem

SnapshotItem

A SnapshotItem is a container that contains a single value that is potentially stored in some storage identified by a unique key - just like an Item. It's worth familiarizing yourself with the Item type first, as everything we talked about there is applicable to SnapshotItem.

On top of that, SnapshotItem makes it a little simpler to maintain a history of values at various block heights. This involves saving "checkpoints" at some points in time - just how that is done is decided by the Strategy (opens in a new tab) type passed to the SnapshotItem constructor.

Strategy

There are currently 3 built-in strategies, although in the future this might be open to extension.

Usage examples

Maintaining a price history

💡

The constructor of SnapshotItem takes 3 "namespace" arguments: - the main namespace, similar to the Item constructor - two additional unique namespaces, which are used to store the changelog metadata

Let's say we want to keep a history of prices for a specific trading pair.

use cw_storage_plus::{SnapshotItem, Strategy};
 
let price: SnapshotItem<Decimal> = SnapshotItem::new("p", "p1", "p2", Strategy::EveryBlock);
 
price
    .save(&mut storage, &Decimal::percent(81), env.block.height)
    .unwrap();
 
advance_height(&mut env, 50); // fast forward 50 blocks
 
price
    .save(&mut storage, &Decimal::percent(92), env.block.height)
    .unwrap();
 
// Before/at the first save, the price was unknown (uninitialized state)
assert_eq!(
    price
        .may_load_at_height(&storage, env.block.height - 60)
        .unwrap(),
    None
);
assert_eq!(
    price
        .may_load_at_height(&storage, env.block.height - 50)
        .unwrap(),
    None
);
 
// Before/at the current block, the price was 0.81
assert_eq!(
    price
        .may_load_at_height(&storage, env.block.height - 49)
        .unwrap(),
    Some(Decimal::percent(81))
);
assert_eq!(
    price
        .may_load_at_height(&storage, env.block.height)
        .unwrap(),
    Some(Decimal::percent(81))
);
 
// After the current block, the price will come up as 0.92
assert_eq!(
    price
        .may_load_at_height(&storage, env.block.height + 1)
        .unwrap(),
    Some(Decimal::percent(92))
);
assert_eq!(
    price
        .may_load_at_height(&storage, env.block.height + 50)
        .unwrap(),
    Some(Decimal::percent(92))
);