cosmos-sdk/store/README.md

130 lines
4.6 KiB
Markdown
Raw Normal View History

2019-02-01 17:03:09 -08:00
# Store
## CacheKV
`cachekv.Store` is a wrapper `KVStore` which provides buffered writing / cached reading functionalities over the underlying `KVStore`.
2019-02-01 17:03:09 -08:00
```go
type Store struct {
cache map[string]cValue
parent types.KVStore
}
```
### Get
feat: ADR-040: Add `RootStore` implementation (#10430) ## Description Part of: https://github.com/cosmos/cosmos-sdk/issues/10192 Introduces a new `RootStore` type in the `store/v2` package and an implementation, without yet replacing the `MultiStore` or refactoring its use within the SDK (which will happen in the follow up: https://github.com/cosmos/cosmos-sdk/pull/10174). Specified by [ADR-040](https://github.com/cosmos/cosmos-sdk/blob/1326fa2a7dfc3d83cf23dc1c1f33ff131152ad60/docs/architecture/adr-040-storage-and-smt-state-commitments.md). Fixes https://github.com/cosmos/cosmos-sdk/issues/10651 Fixes https://github.com/cosmos/cosmos-sdk/issues/10263 --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [x] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [x] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [x] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [x] added a changelog entry to `CHANGELOG.md` - [x] included comments for [documenting Go code](https://blog.golang.org/godoc) - [x] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable)
2021-12-16 05:09:57 -08:00
`Store.Get()` checks `Store.cache` first in order to find if there is any cached value associated with the key. If the value exists, the function returns it. If not, the function calls `Store.parent.Get()`, sets the key-value pair in the `Store.cache`, and returns it.
2019-02-01 17:03:09 -08:00
### Set
`Store.Set()` sets the key-value pair to the `Store.cache`. `cValue` has the field `dirty bool` which indicates whether the cached value is different from the underlying value. When `Store.Set()` cache new pair, the `cValue.dirty` is set true so when `Store.Write()` is called it can be written to the underlying store.
### Iterator
`Store.Iterator()` have to traverse on both caches items and the original items. In `Store.iterator()`, two iterators are generated for each of them, and merged. `memIterator` is essentially a slice of the `KVPair`s, used for cached items. `mergeIterator` is a combination of two iterators, where traverse happens ordered on both iterators.
## CacheMulti
`cachemulti.Store` is a wrapper `MultiStore` which provides buffered writing / cached reading functionalities over the underlying `MutliStore`
```go
type Store struct {
db types.CacheKVStore
stores map[types.StoreKey] types.CacheWrap
}
```
`cachemulti.Store` branches all substores in its constructor and hold them in `Store.stores`. `Store.GetKVStore()` returns the store from `Store.stores`, and `Store.Write()` recursively calls `CacheWrap.Write()` on the substores.
2019-02-01 17:03:09 -08:00
## DBAdapter
`dbadapter.Store` is a adapter for `dbm.DB` making it fulfilling the `KVStore` interface.
```go
type Store struct {
dbm.DB
}
```
`dbadapter.Store` embeds `dbm.DB`, so most of the `KVStore` interface functions are implemented. The other functions(mostly miscellaneous) are manually implemented.
## IAVL
`iavl.Store` is a base-layer self-balancing merkle tree. It is guaranteed that
2019-02-01 17:03:09 -08:00
1. Get & set operations are `O(log n)`, where `n` is the number of elements in the tree
2. Iteration efficiently returns the sorted elements within the range
3. Each tree version is immutable and can be retrieved even after a commit(depending on the pruning settings)
Specification and implementation of IAVL tree can be found in https://github.com/tendermint/iavl.
2019-02-01 17:03:09 -08:00
## GasKV
`gaskv.Store` is a wrapper `KVStore` which provides gas consuming functionalities over the underlying `KVStore`.
```go
type Store struct {
gasMeter types.GasMeter
gasConfig types.GasConfig
parent types.KVStore
}
```
When each `KVStore` methods are called, `gaskv.Store` automatically consumes appropriate amount of gas depending on the `Store.gasConfig`.
## Prefix
`prefix.Store` is a wrapper `KVStore` which provides automatic key-prefixing functionalities over the underlying `KVStore`.
```go
type Store struct {
parent types.KVStore
prefix []byte
}
```
When `Store.{Get, Set}()` is called, the store forwards the call to its parent, with the key prefixed with the `Store.prefix`.
When `Store.Iterator()` is called, it does not simply prefix the `Store.prefix`, since it does not work as intended. In that case, some of the elements are traversed even they are not starting with the prefix.
## RootMulti
`rootmulti.Store` is a base-layer `MultiStore` where multiple `KVStore` can be mounted on it and retrieved via object-capability keys. The keys are memory addresses, so it is impossible to forge the key unless an object is a valid owner(or a receiver) of the key, according to the object capability principles.
## TraceKV
`tracekv.Store` is a wrapper `KVStore` which provides operation tracing functionalities over the underlying `KVStore`.
```go
type Store struct {
parent types.KVStore
writer io.Writer
context types.TraceContext
}
```
When each `KVStore` methods are called, `tracekv.Store` automatically logs `traceOperation` to the `Store.writer`.
```go
type traceOperation struct {
Operation operation
Key string
Value string
Metadata map[string]interface{}
}
2019-02-01 17:03:09 -08:00
```
`traceOperation.Metadata` is filled with `Store.context` when it is not nil. `TraceContext` is a `map[string]interface{}`.
## Transient
`transient.Store` is a base-layer `KVStore` which is automatically discarded at the end of the block.
```go
type Store struct {
dbadapter.Store
}
```
`Store.Store` is a `dbadapter.Store` with a `dbm.NewMemDB()`. All `KVStore` methods are reused. When `Store.Commit()` is called, new `dbadapter.Store` is assigned, discarding previous reference and making it garbage collected.