github.com/Finschia/finschia-sdk@v0.49.1/store/types/store.go (about)

     1  package types
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  
     7  	oststrings "github.com/Finschia/ostracon/libs/strings"
     8  	abci "github.com/tendermint/tendermint/abci/types"
     9  	dbm "github.com/tendermint/tm-db"
    10  
    11  	snapshottypes "github.com/Finschia/finschia-sdk/snapshots/types"
    12  	"github.com/Finschia/finschia-sdk/types/kv"
    13  )
    14  
    15  type Store interface {
    16  	GetStoreType() StoreType
    17  	CacheWrapper
    18  }
    19  
    20  // something that can persist to disk
    21  type Committer interface {
    22  	Commit() CommitID
    23  	LastCommitID() CommitID
    24  
    25  	SetPruning(PruningOptions)
    26  	GetPruning() PruningOptions
    27  }
    28  
    29  // Stores of MultiStore must implement CommitStore.
    30  type CommitStore interface {
    31  	Committer
    32  	Store
    33  }
    34  
    35  // Queryable allows a Store to expose internal state to the abci.Query
    36  // interface. Multistore can route requests to the proper Store.
    37  //
    38  // This is an optional, but useful extension to any CommitStore
    39  type Queryable interface {
    40  	Query(abci.RequestQuery) abci.ResponseQuery
    41  }
    42  
    43  //----------------------------------------
    44  // MultiStore
    45  
    46  // StoreUpgrades defines a series of transformations to apply the multistore db upon load
    47  type StoreUpgrades struct {
    48  	Added   []string      `json:"added"`
    49  	Renamed []StoreRename `json:"renamed"`
    50  	Deleted []string      `json:"deleted"`
    51  }
    52  
    53  // UpgradeInfo defines height and name of the upgrade
    54  // to ensure multistore upgrades happen only at matching height.
    55  type UpgradeInfo struct {
    56  	Name   string `json:"name"`
    57  	Height int64  `json:"height"`
    58  }
    59  
    60  // StoreRename defines a name change of a sub-store.
    61  // All data previously under a PrefixStore with OldKey will be copied
    62  // to a PrefixStore with NewKey, then deleted from OldKey store.
    63  type StoreRename struct {
    64  	OldKey string `json:"old_key"`
    65  	NewKey string `json:"new_key"`
    66  }
    67  
    68  // IsDeleted returns true if the given key should be added
    69  func (s *StoreUpgrades) IsAdded(key string) bool {
    70  	if s == nil {
    71  		return false
    72  	}
    73  	return oststrings.StringInSlice(key, s.Added)
    74  }
    75  
    76  // IsDeleted returns true if the given key should be deleted
    77  func (s *StoreUpgrades) IsDeleted(key string) bool {
    78  	if s == nil {
    79  		return false
    80  	}
    81  	for _, d := range s.Deleted {
    82  		if d == key {
    83  			return true
    84  		}
    85  	}
    86  	return false
    87  }
    88  
    89  // RenamedFrom returns the oldKey if it was renamed
    90  // Returns "" if it was not renamed
    91  func (s *StoreUpgrades) RenamedFrom(key string) string {
    92  	if s == nil {
    93  		return ""
    94  	}
    95  	for _, re := range s.Renamed {
    96  		if re.NewKey == key {
    97  			return re.OldKey
    98  		}
    99  	}
   100  	return ""
   101  }
   102  
   103  type MultiStore interface {
   104  	Store
   105  
   106  	// Branches MultiStore into a cached storage object.
   107  	// NOTE: Caller should probably not call .Write() on each, but
   108  	// call CacheMultiStore.Write().
   109  	CacheMultiStore() CacheMultiStore
   110  
   111  	// CacheMultiStoreWithVersion branches the underlying MultiStore where
   112  	// each stored is loaded at a specific version (height).
   113  	CacheMultiStoreWithVersion(version int64) (CacheMultiStore, error)
   114  
   115  	// Convenience for fetching substores.
   116  	// If the store does not exist, panics.
   117  	GetStore(StoreKey) Store
   118  	GetKVStore(StoreKey) KVStore
   119  
   120  	// TracingEnabled returns if tracing is enabled for the MultiStore.
   121  	TracingEnabled() bool
   122  
   123  	// SetTracer sets the tracer for the MultiStore that the underlying
   124  	// stores will utilize to trace operations. The modified MultiStore is
   125  	// returned.
   126  	SetTracer(w io.Writer) MultiStore
   127  
   128  	// SetTracingContext sets the tracing context for a MultiStore. It is
   129  	// implied that the caller should update the context when necessary between
   130  	// tracing operations. The modified MultiStore is returned.
   131  	SetTracingContext(TraceContext) MultiStore
   132  
   133  	// ListeningEnabled returns if listening is enabled for the KVStore belonging the provided StoreKey
   134  	ListeningEnabled(key StoreKey) bool
   135  
   136  	// AddListeners adds WriteListeners for the KVStore belonging to the provided StoreKey
   137  	// It appends the listeners to a current set, if one already exists
   138  	AddListeners(key StoreKey, listeners []WriteListener)
   139  }
   140  
   141  // From MultiStore.CacheMultiStore()....
   142  type CacheMultiStore interface {
   143  	MultiStore
   144  	Write() // Writes operations to underlying KVStore
   145  }
   146  
   147  // CommitMultiStore is an interface for a MultiStore without cache capabilities.
   148  type CommitMultiStore interface {
   149  	Committer
   150  	MultiStore
   151  	snapshottypes.Snapshotter
   152  
   153  	// Mount a store of type using the given db.
   154  	// If db == nil, the new store will use the CommitMultiStore db.
   155  	MountStoreWithDB(key StoreKey, typ StoreType, db dbm.DB)
   156  
   157  	// Panics on a nil key.
   158  	GetCommitStore(key StoreKey) CommitStore
   159  
   160  	// Panics on a nil key.
   161  	GetCommitKVStore(key StoreKey) CommitKVStore
   162  
   163  	// Load the latest persisted version. Called once after all calls to
   164  	// Mount*Store() are complete.
   165  	LoadLatestVersion() error
   166  
   167  	// LoadLatestVersionAndUpgrade will load the latest version, but also
   168  	// rename/delete/create sub-store keys, before registering all the keys
   169  	// in order to handle breaking formats in migrations
   170  	LoadLatestVersionAndUpgrade(upgrades *StoreUpgrades) error
   171  
   172  	// LoadVersionAndUpgrade will load the named version, but also
   173  	// rename/delete/create sub-store keys, before registering all the keys
   174  	// in order to handle breaking formats in migrations
   175  	LoadVersionAndUpgrade(ver int64, upgrades *StoreUpgrades) error
   176  
   177  	// Load a specific persisted version. When you load an old version, or when
   178  	// the last commit attempt didn't complete, the next commit after loading
   179  	// must be idempotent (return the same commit id). Otherwise the behavior is
   180  	// undefined.
   181  	LoadVersion(ver int64) error
   182  
   183  	// Set an inter-block (persistent) cache that maintains a mapping from
   184  	// StoreKeys to CommitKVStores.
   185  	SetInterBlockCache(MultiStorePersistentCache)
   186  
   187  	// SetInitialVersion sets the initial version of the IAVL tree. It is used when
   188  	// starting a new chain at an arbitrary height.
   189  	SetInitialVersion(version int64) error
   190  
   191  	// SetIAVLCacheSize sets the cache size of the IAVL tree.
   192  	SetIAVLCacheSize(size int)
   193  
   194  	// SetIAVLDisableFastNode enables/disables fastnode feature on iavl.
   195  	SetIAVLDisableFastNode(disable bool)
   196  
   197  	// RollbackToVersion rollback the db to specific version(height).
   198  	RollbackToVersion(version int64) error
   199  }
   200  
   201  //---------subsp-------------------------------
   202  // KVStore
   203  
   204  // KVStore is a simple interface to get/set data
   205  type KVStore interface {
   206  	Store
   207  
   208  	// Get returns nil if key doesn't exist. Panics on nil key.
   209  	Get(key []byte) []byte
   210  
   211  	// Has checks if a key exists. Panics on nil key.
   212  	Has(key []byte) bool
   213  
   214  	// Set sets the key. Panics on nil key or value.
   215  	Set(key, value []byte)
   216  
   217  	// Delete deletes the key. Panics on nil key.
   218  	Delete(key []byte)
   219  
   220  	// Iterator over a domain of keys in ascending order. End is exclusive.
   221  	// Start must be less than end, or the Iterator is invalid.
   222  	// Iterator must be closed by caller.
   223  	// To iterate over entire domain, use store.Iterator(nil, nil)
   224  	// CONTRACT: No writes may happen within a domain while an iterator exists over it.
   225  	// Exceptionally allowed for cachekv.Store, safe to write in the modules.
   226  	Iterator(start, end []byte) Iterator
   227  
   228  	// Iterator over a domain of keys in descending order. End is exclusive.
   229  	// Start must be less than end, or the Iterator is invalid.
   230  	// Iterator must be closed by caller.
   231  	// CONTRACT: No writes may happen within a domain while an iterator exists over it.
   232  	// Exceptionally allowed for cachekv.Store, safe to write in the modules.
   233  	ReverseIterator(start, end []byte) Iterator
   234  }
   235  
   236  // Iterator is an alias db's Iterator for convenience.
   237  type Iterator = dbm.Iterator
   238  
   239  // CacheKVStore branches a KVStore and provides read cache functionality.
   240  // After calling .Write() on the CacheKVStore, all previously created
   241  // CacheKVStores on the object expire.
   242  type CacheKVStore interface {
   243  	KVStore
   244  
   245  	// Writes operations to underlying KVStore
   246  	Write()
   247  }
   248  
   249  // CommitKVStore is an interface for MultiStore.
   250  type CommitKVStore interface {
   251  	Committer
   252  	KVStore
   253  }
   254  
   255  //----------------------------------------
   256  // CacheWrap
   257  
   258  // CacheWrap is the most appropriate interface for store ephemeral branching and cache.
   259  // For example, IAVLStore.CacheWrap() returns a CacheKVStore. CacheWrap should not return
   260  // a Committer, since Commit ephemeral store make no sense. It can return KVStore,
   261  // HeapStore, SpaceStore, etc.
   262  type CacheWrap interface {
   263  	// Write syncs with the underlying store.
   264  	Write()
   265  
   266  	// CacheWrap recursively wraps again.
   267  	CacheWrap() CacheWrap
   268  
   269  	// CacheWrapWithTrace recursively wraps again with tracing enabled.
   270  	CacheWrapWithTrace(w io.Writer, tc TraceContext) CacheWrap
   271  
   272  	// CacheWrapWithListeners recursively wraps again with listening enabled
   273  	CacheWrapWithListeners(storeKey StoreKey, listeners []WriteListener) CacheWrap
   274  }
   275  
   276  type CacheWrapper interface {
   277  	// CacheWrap branches a store.
   278  	CacheWrap() CacheWrap
   279  
   280  	// CacheWrapWithTrace branches a store with tracing enabled.
   281  	CacheWrapWithTrace(w io.Writer, tc TraceContext) CacheWrap
   282  
   283  	// CacheWrapWithListeners recursively wraps again with listening enabled
   284  	CacheWrapWithListeners(storeKey StoreKey, listeners []WriteListener) CacheWrap
   285  }
   286  
   287  func (cid CommitID) IsZero() bool {
   288  	return cid.Version == 0 && len(cid.Hash) == 0
   289  }
   290  
   291  func (cid CommitID) String() string {
   292  	return fmt.Sprintf("CommitID{%v:%X}", cid.Hash, cid.Version)
   293  }
   294  
   295  //----------------------------------------
   296  // Store types
   297  
   298  // kind of store
   299  type StoreType int
   300  
   301  const (
   302  	StoreTypeMulti StoreType = iota
   303  	StoreTypeDB
   304  	StoreTypeIAVL
   305  	StoreTypeTransient
   306  	StoreTypeMemory
   307  )
   308  
   309  func (st StoreType) String() string {
   310  	switch st {
   311  	case StoreTypeMulti:
   312  		return "StoreTypeMulti"
   313  
   314  	case StoreTypeDB:
   315  		return "StoreTypeDB"
   316  
   317  	case StoreTypeIAVL:
   318  		return "StoreTypeIAVL"
   319  
   320  	case StoreTypeTransient:
   321  		return "StoreTypeTransient"
   322  
   323  	case StoreTypeMemory:
   324  		return "StoreTypeMemory"
   325  	}
   326  
   327  	return "unknown store type"
   328  }
   329  
   330  //----------------------------------------
   331  // Keys for accessing substores
   332  
   333  // StoreKey is a key used to index stores in a MultiStore.
   334  type StoreKey interface {
   335  	Name() string
   336  	String() string
   337  }
   338  
   339  // CapabilityKey represent the Cosmos SDK keys for object-capability
   340  // generation in the IBC protocol as defined in https://github.com/cosmos/ics/tree/master/spec/ics-005-port-allocation#data-structures
   341  type CapabilityKey StoreKey
   342  
   343  // KVStoreKey is used for accessing substores.
   344  // Only the pointer value should ever be used - it functions as a capabilities key.
   345  type KVStoreKey struct {
   346  	name string
   347  }
   348  
   349  // NewKVStoreKey returns a new pointer to a KVStoreKey.
   350  // Use a pointer so keys don't collide.
   351  func NewKVStoreKey(name string) *KVStoreKey {
   352  	if name == "" {
   353  		panic("empty key name not allowed")
   354  	}
   355  	return &KVStoreKey{
   356  		name: name,
   357  	}
   358  }
   359  
   360  func (key *KVStoreKey) Name() string {
   361  	return key.name
   362  }
   363  
   364  func (key *KVStoreKey) String() string {
   365  	return fmt.Sprintf("KVStoreKey{%p, %s}", key, key.name)
   366  }
   367  
   368  // TransientStoreKey is used for indexing transient stores in a MultiStore
   369  type TransientStoreKey struct {
   370  	name string
   371  }
   372  
   373  // Constructs new TransientStoreKey
   374  // Must return a pointer according to the ocap principle
   375  func NewTransientStoreKey(name string) *TransientStoreKey {
   376  	return &TransientStoreKey{
   377  		name: name,
   378  	}
   379  }
   380  
   381  // Implements StoreKey
   382  func (key *TransientStoreKey) Name() string {
   383  	return key.name
   384  }
   385  
   386  // Implements StoreKey
   387  func (key *TransientStoreKey) String() string {
   388  	return fmt.Sprintf("TransientStoreKey{%p, %s}", key, key.name)
   389  }
   390  
   391  // MemoryStoreKey defines a typed key to be used with an in-memory KVStore.
   392  type MemoryStoreKey struct {
   393  	name string
   394  }
   395  
   396  func NewMemoryStoreKey(name string) *MemoryStoreKey {
   397  	return &MemoryStoreKey{name: name}
   398  }
   399  
   400  // Name returns the name of the MemoryStoreKey.
   401  func (key *MemoryStoreKey) Name() string {
   402  	return key.name
   403  }
   404  
   405  // String returns a stringified representation of the MemoryStoreKey.
   406  func (key *MemoryStoreKey) String() string {
   407  	return fmt.Sprintf("MemoryStoreKey{%p, %s}", key, key.name)
   408  }
   409  
   410  //----------------------------------------
   411  
   412  // key-value result for iterator queries
   413  type KVPair kv.Pair
   414  
   415  //----------------------------------------
   416  
   417  // TraceContext contains TraceKVStore context data. It will be written with
   418  // every trace operation.
   419  type TraceContext map[string]interface{}
   420  
   421  // MultiStorePersistentCache defines an interface which provides inter-block
   422  // (persistent) caching capabilities for multiple CommitKVStores based on StoreKeys.
   423  type MultiStorePersistentCache interface {
   424  	// Wrap and return the provided CommitKVStore with an inter-block (persistent)
   425  	// cache.
   426  	GetStoreCache(key StoreKey, store CommitKVStore) CommitKVStore
   427  
   428  	// Return the underlying CommitKVStore for a StoreKey.
   429  	Unwrap(key StoreKey) CommitKVStore
   430  
   431  	// Reset the entire set of internal caches.
   432  	Reset()
   433  }
   434  
   435  // StoreWithInitialVersion is a store that can have an arbitrary initial
   436  // version.
   437  type StoreWithInitialVersion interface {
   438  	// SetInitialVersion sets the initial version of the IAVL tree. It is used when
   439  	// starting a new chain at an arbitrary height.
   440  	SetInitialVersion(version int64)
   441  }