Skip to content

Commit

Permalink
storage-plus: document SnapshotMap
Browse files Browse the repository at this point in the history
  • Loading branch information
uint committed Aug 8, 2024
1 parent 426df27 commit da22da6
Showing 1 changed file with 106 additions and 0 deletions.
106 changes: 106 additions & 0 deletions src/pages/cw-storage-plus/containers/snapshot-map.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
---
tags: ["storage-plus", "containers"]
---

import { Callout } from "nextra/components";

# SnapshotMap

A `SnapshotMap` is a key-value store like [`Map`]. It's worth familiarizing yourself with the `Map`
type first, as everything we talked about there is applicable to `SnapshotMap`.

On top of that, `SnapshotMap` 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`] type passed to the `SnapshotMap` constructor.

# Strategy

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

- `EveryBlock` - a checkpoint is (conceptually) added at the beginning of every block, and
historical data is available for any height
- `Never` - there's never a checkpoint saved, and the `SnapshotMap` is no different from a regular
`Map` in terms of features. Any call to [`may_load_at_height`] will return `StdError::NotFound`
- `Selected` - the [`add_checkpoint`] method has to be called manually to add a checkpoint at the
given height. Keep in mind that when calling [`may_load_at_height`] later, the height has to be
the same as the one passed to [`add_checkpoint`]. If you try to load a value at a height when no
checkpoint was saved, the method will return [`StdError::NotFound`].

## Usage examples

### Maintaining price histories for various trading pairs

<Callout>
The constructor of `SnapshotMap` takes 3 "namespace" arguments: - the main namespace, similar to
the `Map` constructor - two additional unique namespaces, which are used to store the changelog
metadata
</Callout>

```rust template="storage"
use cw_storage_plus::{SnapshotMap, Strategy};

let price: SnapshotMap<(&str, &str), Decimal> = SnapshotMap::new("p", "p1", "p2", Strategy::EveryBlock);

price
.save(&mut storage, ("OSMO", "ATOM"), &Decimal::percent(81), env.block.height)
.unwrap();

advance_height(&mut env, 50); // fast forward 50 blocks

price
.save(&mut storage, ("OSMO", "ATOM"), &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, ("OSMO", "ATOM"), env.block.height - 60)
.unwrap(),
None
);
assert_eq!(
price
.may_load_at_height(&storage, ("OSMO", "ATOM"), env.block.height - 50)
.unwrap(),
None
);

// Before/at the current block, the price was 81%
assert_eq!(
price
.may_load_at_height(&storage, ("OSMO", "ATOM"), env.block.height - 49)
.unwrap(),
Some(Decimal::percent(81))
);
assert_eq!(
price
.may_load_at_height(&storage, ("OSMO", "ATOM"), env.block.height)
.unwrap(),
Some(Decimal::percent(81))
);

// After the current block, the price will come up as 92%
assert_eq!(
price
.may_load_at_height(&storage, ("OSMO", "ATOM"), env.block.height + 1)
.unwrap(),
Some(Decimal::percent(92))
);
assert_eq!(
price
.may_load_at_height(&storage, ("OSMO", "ATOM"), env.block.height + 50)
.unwrap(),
Some(Decimal::percent(92))
);
```

[`Map`]: map
[`Strategy`]: https://docs.rs/cw-storage-plus/latest/cw_storage_plus/enum.Strategy.html
[`add_checkpoint`]:
https://docs.rs/cw-storage-plus/latest/cw_storage_plus/struct.SnapshotMap.html#method.add_checkpoint
[`may_load_at_height`]:
https://docs.rs/cw-storage-plus/latest/cw_storage_plus/struct.SnapshotMap.html#method.may_load_at_height
[`StdError::NotFound`]:
https://docs.rs/cosmwasm-std/latest/cosmwasm_std/enum.StdError.html#variant.NotFound
[`serde`]: https://serde.rs/
[API docs]: https://docs.rs/cw-storage-plus/latest/cw_storage_plus/struct.SnapshotMap.html

0 comments on commit da22da6

Please sign in to comment.