Skip to content

Commit 8c787eb

Browse files
committed
Add Pinning docs
1 parent 453f297 commit 8c787eb

File tree

1 file changed

+78
-0
lines changed

1 file changed

+78
-0
lines changed

docs/PINNING.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Contract pinning
2+
3+
Contract pinning is a feature of the CosmWasm virtual machine which ensures that
4+
a previously stored compiled contract code (module) is started from a dedicated
5+
in-memory cache. Starting a module from memory takes ~45µs compared to 1.5ms
6+
when loaded from disk (33x faster).
7+
8+
In contast to the node specific Least recently used (LRU) memory cache, pinning
9+
**guarantees** this performance boost across the network. As a consequence wasmd
10+
can charge discounted gas cost[^1].
11+
12+
## The caches
13+
14+
CosmWasm has 3 different caches for modules:
15+
16+
1. `FileSystemCache` the `.module` files stored in the cache directory of the
17+
node
18+
2. `InMemoryCache` the LRU cache
19+
3. `PinnedMemoryCache` a separate cache
20+
21+
Both memory caches (2./3.) work the same in terms of performance but their
22+
elements are tracked separately. A pinned contract is never added to the
23+
standard `InMemoryCache` and the size of pinned contracts is not counted towards
24+
its cache size limit.
25+
26+
## Pinning and Unpinning
27+
28+
In order to add a contract to the `PinnedMemoryCache`, you need to call
29+
[`Cache::pin`] in Rust or `func (vm *VM) Pin(checksum Checksum) error` in
30+
wasmvm. To remove a contract from the cache use [`Cache::unpin`] /
31+
`func (vm *VM) Unpin(checksum Checksum) error`. In both cases a contract is
32+
identified by its checksum (sha256 hash of the Wasm blob).
33+
34+
The VM does not persist pinned memory entries. I.e. you need to call `Pin` every
35+
time you start the process. This is implemented in [`InitializePinnedCodes` in
36+
wasmd][initializepinnedcodes].
37+
38+
At the chain level pinning and unpinning is done via governance proposals. See
39+
`MsgPinCodes`/`MsgUnpinCodes` in wasmd.
40+
41+
When contracts are migrated from one code to another, there is no automatic
42+
pinning or unpinning. This is primarily since the migration of a single instance
43+
does not means all instances of the same code become unused. In the future we
44+
want to provide hit stats for each checksum in order to easily find unused codes
45+
in the pinned memory cache[^2].
46+
47+
## Best practices
48+
49+
Pinning contracts is a balance between increasing memory usage and boosting
50+
execution speed. Contracts that are known to be heavily used should be pinned.
51+
This can includes contracts that are executed as part of begin/end block or the
52+
IBC light client implementations of the Wasm Light Client ([08-wasm]). If a
53+
chain is permissioned and runs on a small number of well known contracts, they
54+
can all be pinned. A permissionless chain might select certain contracts of
55+
strategic importance and pin them.
56+
57+
The estimated size of the pinned contracts is visible in the [Metrics] struct
58+
you can access through [Prometheus](https://prometheus.io/).
59+
60+
## History
61+
62+
Pinning was developed in 2021 (CosmWasm 0.14) for the Proof of Engagement
63+
consensus system of Tgrade which required certain contracts to be executed in
64+
every block.
65+
66+
[metrics]:
67+
https://github.com/CosmWasm/wasmvm/blob/v2.0.0-rc.2/types/types.go#L174-L185
68+
[`cache::pin`]:
69+
https://docs.rs/cosmwasm-vm/latest/cosmwasm_vm/struct.Cache.html#method.pin
70+
[`cache::unpin`]:
71+
https://docs.rs/cosmwasm-vm/latest/cosmwasm_vm/struct.Cache.html#method.unpin
72+
[08-wasm]:
73+
https://github.com/cosmos/ibc-go/tree/main/modules/light-clients/08-wasm
74+
[initializepinnedcodes]:
75+
https://github.com/CosmWasm/wasmd/blob/v0.50.0/x/wasm/keeper/keeper.go#L1011-L1028
76+
77+
[^1]: https://github.com/CosmWasm/wasmd/pull/1799
78+
[^2]: https://github.com/CosmWasm/cosmwasm/issues/2034

0 commit comments

Comments
 (0)