README
¶
Store
The store
package contains the implementation of store/v2, which is the SDK's
abstraction around managing historical and committed state. See ADR-065
and Store v2 Design for a high-level overview of the design and rationale.
Usage
The store
package contains a root.Store
type which is intended to act as an
abstraction layer around it's primary constituent components - state commitment (SC). It acts as the main entry point into storage for an
application to use in server/v2. Through root.Store
, an application can query
and iterate over both current and historical data, commit new state, perform state
sync, and fetch commitment proofs.
A root.Store
is intended to be initialized with already constructed SS and SC
backends (see relevant package documentation for instantiation details). Note,
from the perspective of root.Store
, there is no notion of multi or single tree/store,
rather these are implementation details of SC. For SC, we utilize an abstraction, commitment.CommitStore
,
to map store keys to a commitment trees.
Upgrades
The LoadVersionAndUpgrade
API of the root.store
allows for adding or removing
store keys. This is useful for upgrading the chain with new modules or removing
old ones. The Rename
feature is not supported in store/v2.
sequenceDiagram
participant S as Store
participant SC as StateCommitment
alt SC is a UpgradeableStore
S->>SC: LoadVersionAndUpgrade
SC->>SC: Mount new store keys
SC->>SC: Prune removed store keys
end
SC->>S: LoadVersion Result
PruneStoreKeys
does not remove the data from the SC instantly. It only
marks the store keys as pruned. The actual data removal is done by the pruning
process of the underlying SC.
Migration
The migration from store/v1 to store/v2 is supported by the MigrationManager
in
the migration
package. See Migration Manager for more details.
Pruning
The root.Store
is NOT responsible for pruning. Rather, pruning is the responsibility
of the underlying commitment layer. This means pruning can be implementation specific,
such as being synchronous or asynchronous. See Pruning Manager for more details.
State Sync
The root.Store
is NOT responsible for state sync. See Snapshots Manager
for more details.
Test Coverage
The test coverage of the following logical components should be over 60%:
Documentation
¶
Index ¶
- Variables
- func AssertValidKey(key []byte)
- func AssertValidValue(value []byte)
- type Backend
- type Batch
- type Committer
- type PausablePruner
- type Pruner
- type PruningOption
- type PruningStrategy
- type QueryResult
- type RootStore
- type TraceContext
- type UpgradableDatabase
- type UpgradeableStore
- type VersionedReader
Constants ¶
This section is empty.
Variables ¶
var ( // MaxKeyLength is the maximum allowed length for a key in bytes. // It is set to 128K - 1 (131,071 bytes). MaxKeyLength = (1 << 17) - 1 // MaxValueLength is the maximum allowed length for a value in bytes. // It is set to 2G - 1 (2,147,483,647 bytes). MaxValueLength = (1 << 31) - 1 )
Functions ¶
func AssertValidKey ¶
func AssertValidKey(key []byte)
AssertValidKey checks if the key is valid, i.e. key is not nil, not empty and within length limit.
func AssertValidValue ¶
func AssertValidValue(value []byte)
AssertValidValue checks if the value is valid, i.e. value is not nil and within length limit.
Types ¶
type Backend ¶
type Backend interface { // GetStateCommitment returns the SC backend. GetStateCommitment() Committer }
Backend defines the interface for the RootStore backends.
type Batch ¶
type Batch interface { // Set inserts the given value into the key-value data store. // // Note: <key, value> are safe to modify and read after calling Set. Set(storeKey, key, value []byte) error // Delete removes the key from the backing key-value data store. // // Note: <key> is safe to modify and read after calling Delete. Delete(storeKey, key []byte) error // Size retrieves the amount of data queued up for writing, this includes // the keys, values, and deleted keys. Size() int // Write flushes any accumulated data to disk. Write() error // Reset resets the batch. Reset() error }
Batch is a write-only database that commits changes to the underlying database when Write is called. A batch cannot be used concurrently.
type Committer ¶
type Committer interface { UpgradeableStore VersionedReader // WriteChangeset writes the changeset to the commitment state. WriteChangeset(cs *corestore.Changeset) error // GetLatestVersion returns the latest version. GetLatestVersion() (uint64, error) // LoadVersion loads the tree at the given version. LoadVersion(targetVersion uint64) error // LoadVersionForOverwriting loads the tree at the given version. // Any versions greater than targetVersion will be deleted. LoadVersionForOverwriting(targetVersion uint64) error // Commit commits the working tree to the database. Commit(version uint64) (*proof.CommitInfo, error) // GetProof returns the proof of existence or non-existence for the given key. GetProof(storeKey []byte, version uint64, key []byte) ([]proof.CommitmentOp, error) // SetInitialVersion sets the initial version of the committer. SetInitialVersion(version uint64) error // GetCommitInfo returns the CommitInfo for the given version. GetCommitInfo(version uint64) (*proof.CommitInfo, error) Get(storeKey []byte, version uint64, key []byte) ([]byte, error) // Closer releases associated resources. It should NOT be idempotent. It must // only be called once and any call after may panic. io.Closer }
Committer defines an API for committing state.
type PausablePruner ¶
type PausablePruner interface { Pruner // PausePruning pauses or resumes the pruning process to avoid the parallel writes // while committing the state. PausePruning(pause bool) }
PausablePruner extends the Pruner interface to include the API for pausing the pruning process.
type Pruner ¶
type Pruner interface { // Prune prunes the store to the provided version. Prune(version uint64) error }
Pruner defines the interface for pruning old versions of the store or database.
type PruningOption ¶
type PruningOption struct { // KeepRecent sets the number of recent versions to keep. KeepRecent uint64 `mapstructure:"keep-recent" toml:"keep-recent" comment:"Number of recent heights to keep on disk."` // Interval sets the number of how often to prune. // If set to 0, no pruning will be done. Interval uint64 `mapstructure:"interval" toml:"interval" comment:"Height interval at which pruned heights are removed from disk."` }
PruningOption defines the pruning configuration. app.toml config options
func NewPruningOption ¶
func NewPruningOption(pruningStrategy PruningStrategy) *PruningOption
NewPruningOption returns a new PruningOption instance based on the given pruning strategy.
func NewPruningOptionWithCustom ¶
func NewPruningOptionWithCustom(keepRecent, interval uint64) *PruningOption
NewPruningOptionWithCustom returns a new PruningOption based on the given parameters.
func (*PruningOption) ShouldPrune ¶
func (opts *PruningOption) ShouldPrune(version uint64) (bool, uint64)
ShouldPrune returns true if the given version should be pruned. If true, it also returns the version to prune up to. NOTE: The current version is not pruned.
type PruningStrategy ¶
type PruningStrategy int
const ( // PruningDefault defines a pruning strategy where the last 362880 heights are // kept where to-be pruned heights are pruned at every 10th height. // The last 362880 heights are kept(approximately 3.5 weeks worth of state) assuming the typical // block time is 6s. If these values do not match the applications' requirements, use the "custom" option. PruningDefault PruningStrategy = iota // PruningEverything defines a pruning strategy where all committed heights are // deleted, storing only the current height and last 2 states. To-be pruned heights are // pruned at every 10th height. PruningEverything // PruningNothing defines a pruning strategy where all heights are kept on disk. // This is the only stretegy where KeepEvery=1 is allowed with state-sync snapshots disabled. PruningNothing )
type QueryResult ¶
type QueryResult struct { Key []byte Value []byte Version uint64 ProofOps []proof.CommitmentOp }
QueryResult defines the response type to performing a query on a RootStore.
type RootStore ¶
type RootStore interface { Pruner Backend // StateLatest returns a read-only version of the RootStore at the latest // height, alongside the associated version. StateLatest() (uint64, corestore.ReaderMap, error) // StateAt is analogous to StateLatest() except it returns a read-only version // of the RootStore at the provided version. If such a version cannot be found, // an error must be returned. StateAt(version uint64) (corestore.ReaderMap, error) // Query performs a query on the RootStore for a given store key, version (height), // and key tuple. Queries should be routed to the underlying SS engine. Query(storeKey []byte, version uint64, key []byte, prove bool) (QueryResult, error) // LoadVersion loads the RootStore to the given version. LoadVersion(version uint64) error // LoadVersionForOverwriting loads the state at the given version. // Any versions greater than targetVersion will be deleted. LoadVersionForOverwriting(version uint64) error // LoadLatestVersion behaves identically to LoadVersion except it loads the // latest version implicitly. LoadLatestVersion() error // GetLatestVersion returns the latest version, i.e. height, committed. GetLatestVersion() (uint64, error) // SetInitialVersion sets the initial version on the RootStore. SetInitialVersion(v uint64) error // Commit should be responsible for taking the provided changeset and flushing // it to disk. Note, it will overwrite the changeset if WorkingHash() was called. // Commit() should ensure the changeset is committed to all SC and SS backends // and flushed to disk. It must return a hash of the merkle-ized committed state. Commit(cs *corestore.Changeset) ([]byte, error) // LastCommitID returns a CommitID pertaining to the last commitment. LastCommitID() (proof.CommitID, error) // SetMetrics sets the telemetry handler on the RootStore. SetMetrics(m metrics.Metrics) io.Closer }
RootStore defines an abstraction layer containing a State Storage (SS) engine and one or more State Commitment (SC) engines.
type TraceContext ¶
TraceContext contains KVStore context data. It will be written with every trace operation.
func (TraceContext) Clone ¶
func (tc TraceContext) Clone() TraceContext
Clone creates a shallow clone of a TraceContext.
func (TraceContext) Merge ¶
func (tc TraceContext) Merge(newTc TraceContext) TraceContext
Merge merges the receiver TraceContext with the provided TraceContext argument.
type UpgradableDatabase ¶
type UpgradableDatabase interface { // PruneStoreKeys prunes all data associated with the given storeKeys whenever // the given version is pruned. PruneStoreKeys(storeKeys []string, version uint64) error }
UpgradableDatabase defines an API for a versioned database that allows pruning deleted storeKeys
type UpgradeableStore ¶
type UpgradeableStore interface { // LoadVersionAndUpgrade behaves identically to LoadVersion except it also // accepts a StoreUpgrades object that defines a series of transformations to // apply to store keys (if any). // // Note, handling StoreUpgrades is optional depending on the underlying store // implementation. LoadVersionAndUpgrade(version uint64, upgrades *corestore.StoreUpgrades) error }
UpgradeableStore defines the interface for upgrading store keys.
type VersionedReader ¶
type VersionedReader interface { Has(storeKey []byte, version uint64, key []byte) (bool, error) Get(storeKey []byte, version uint64, key []byte) ([]byte, error) GetLatestVersion() (uint64, error) VersionExists(v uint64) (bool, error) Iterator(storeKey []byte, version uint64, start, end []byte) (corestore.Iterator, error) ReverseIterator(storeKey []byte, version uint64, start, end []byte) (corestore.Iterator, error) }