v0.2300.9 Latest Latest

This package is not in the latest version of its module.

Go to latest
Published: Nov 30, 2023 License: Apache-2.0 Imports: 19 Imported by: 2



Package api implements the storage backend API.



View Source
const (
	// ModuleName is the storage module name.
	ModuleName = "storage"

	// WriteLogIteratorChunkSize defines the chunk size of write log entries
	// for the GetDiff method.
	WriteLogIteratorChunkSize = 10
View Source
const (
	// RootTypeInvalid is an invalid/uninitialized root type.
	RootTypeInvalid = mkvsNode.RootTypeInvalid
	// RootTypeState is the type for state storage roots.
	RootTypeState = mkvsNode.RootTypeState
	// RootTypeIO is the type for IO storage roots.
	RootTypeIO = mkvsNode.RootTypeIO
	// RootTypeMax is the number of different root types.
	RootTypeMax = mkvsNode.RootTypeMax


View Source
var (
	// ErrCantProve is the error returned when the backend is incapable
	// of generating proofs (unsupported, no key, etc).
	ErrCantProve = errors.New(ModuleName, 1, "storage: unable to provide proofs")
	// ErrNoRoots is the error returned when the generated receipt would
	// not contain any roots.
	ErrNoRoots = errors.New(ModuleName, 2, "storage: no roots to generate receipt for")
	// ErrExpectedRootMismatch is the error returned when the expected root
	// does not match the computed root.
	ErrExpectedRootMismatch = errors.New(ModuleName, 3, "storage: expected root mismatch")
	// ErrUnsupported is the error returned when the called method is not
	// supported by the given backend.
	ErrUnsupported = errors.New(ModuleName, 4, "storage: method not supported by backend")
	// ErrLimitReached means that a configured limit has been reached.
	ErrLimitReached = errors.New(ModuleName, 5, "storage: limit reached")

	// ErrNodeNotFound indicates that a node with the specified hash couldn't be found
	// in the database.
	ErrNodeNotFound = nodedb.ErrNodeNotFound
	// ErrWriteLogNotFound indicates that a write log for the specified storage hashes
	// couldn't be found.
	ErrWriteLogNotFound = nodedb.ErrWriteLogNotFound
	// ErrNotFinalized indicates that the operation requires a version to be finalized
	// but the version is not yet finalized.
	ErrNotFinalized = nodedb.ErrNotFinalized
	// ErrAlreadyFinalized indicates that the given version has already been finalized.
	ErrAlreadyFinalized = nodedb.ErrAlreadyFinalized
	// ErrVersionNotFound indicates that the given version cannot be found.
	ErrVersionNotFound = nodedb.ErrVersionNotFound
	// ErrPreviousVersionMismatch indicates that the version given for the old root does
	// not match the previous version.
	ErrPreviousVersionMismatch = nodedb.ErrPreviousVersionMismatch
	// ErrVersionWentBackwards indicates that the new version is earlier than an already
	// inserted version.
	ErrVersionWentBackwards = nodedb.ErrVersionWentBackwards
	// ErrRootNotFound indicates that the given root cannot be found.
	ErrRootNotFound = nodedb.ErrRootNotFound
	// ErrRootMustFollowOld indicates that the passed new root does not follow old root.
	ErrRootMustFollowOld = nodedb.ErrRootMustFollowOld
	// ErrReadOnly indicates that the storage backend is read-only.
	ErrReadOnly = nodedb.ErrReadOnly
View Source
var (

	// ServiceName is the gRPC service name.
	ServiceName = cmnGrpc.NewServiceName("Storage")

	// MethodSyncGet is the SyncGet method.
	MethodSyncGet = ServiceName.NewMethod("SyncGet", GetRequest{}).
					WithNamespaceExtractor(func(ctx context.Context, req interface{}) (common.Namespace, error) {
			r, ok := req.(*GetRequest)
			if !ok {
				return common.Namespace{}, errInvalidRequestType
			return r.Tree.Root.Namespace, nil
	// MethodSyncGetPrefixes is the SyncGetPrefixes method.
	MethodSyncGetPrefixes = ServiceName.NewMethod("SyncGetPrefixes", GetPrefixesRequest{}).
							WithNamespaceExtractor(func(ctx context.Context, req interface{}) (common.Namespace, error) {
			r, ok := req.(*GetPrefixesRequest)
			if !ok {
				return common.Namespace{}, errInvalidRequestType
			return r.Tree.Root.Namespace, nil
	// MethodSyncIterate is the SyncIterate method.
	MethodSyncIterate = ServiceName.NewMethod("SyncIterate", IterateRequest{}).
						WithNamespaceExtractor(func(ctx context.Context, req interface{}) (common.Namespace, error) {
			r, ok := req.(*IterateRequest)
			if !ok {
				return common.Namespace{}, errInvalidRequestType
			return r.Tree.Root.Namespace, nil

	// MethodGetDiff is the GetDiff method.
	MethodGetDiff = ServiceName.NewMethod("GetDiff", GetDiffRequest{})

	// MethodGetCheckpoints is the GetCheckpoints method.
	MethodGetCheckpoints = ServiceName.NewMethod("GetCheckpoints", checkpoint.GetCheckpointsRequest{})

	// MethodGetCheckpointChunk is the GetCheckpointChunk method.
	MethodGetCheckpointChunk = ServiceName.NewMethod("GetCheckpointChunk", checkpoint.ChunkMetadata{})


func RegisterService

func RegisterService(server *grpc.Server, service Backend)

RegisterService registers a new sentry service with the given gRPC server.


type ApplyRequest

type ApplyRequest struct {
	Namespace common.Namespace `json:"namespace"`
	RootType  RootType         `json:"root_type"`
	SrcRound  uint64           `json:"src_round"`
	SrcRoot   hash.Hash        `json:"src_root"`
	DstRound  uint64           `json:"dst_round"`
	DstRoot   hash.Hash        `json:"dst_root"`
	WriteLog  WriteLog         `json:"writelog"`

ApplyRequest is an Apply request.

type Backend

type Backend interface {

	// GetDiff returns an iterator of write log entries that must be applied
	// to get from the first given root to the second one.
	GetDiff(ctx context.Context, request *GetDiffRequest) (WriteLogIterator, error)

	// Cleanup closes/cleans up the storage backend.

	// Initialized returns a channel that will be closed when the
	// backend is initialized and ready to service requests.
	Initialized() <-chan struct{}

Backend is a storage backend implementation.

func NewMetricsWrapper added in v0.2012.3

func NewMetricsWrapper(base Backend) Backend

func NewStorageClient

func NewStorageClient(c *grpc.ClientConn) Backend

NewStorageClient creates a new gRPC storage client service.

type ClientBackend

type ClientBackend interface {

	// GetConnectedNodes returns currently connected storage nodes.
	GetConnectedNodes() []*node.Node

	// EnsureCommitteeVersion waits for the storage committee client to be fully
	// synced to the given version.
	// This method will error in case the storage-client is not configured to
	// track a specific committee.
	EnsureCommitteeVersion(ctx context.Context, version int64) error

ClientBackend is a storage client backend implementation.

type Config

type Config struct {
	// Backend is the database backend.
	Backend string

	// DB is the path to the database.
	DB string

	// Namespace is the namespace contained within the database.
	Namespace common.Namespace

	// MaxCacheSize is the maximum in-memory cache size for the database.
	MaxCacheSize int64

	// DiscardWriteLogs will cause all write logs to be discarded.
	DiscardWriteLogs bool

	// NoFsync will disable fsync() where possible.
	NoFsync bool

	// MemoryOnly will make the storage memory-only (if the backend supports it).
	MemoryOnly bool

	// ReadOnly will make the storage read-only.
	ReadOnly bool

Config is the storage backend configuration.

func (*Config) ToNodeDB

func (cfg *Config) ToNodeDB() *nodedb.Config

ToNodeDB converts from a Config to a node DB Config.

type Depth

type Depth = mkvsNode.Depth

Depth determines the node's (bit) depth in the tree. It is also used for storing the Key length in bits.

type GetDiffRequest

type GetDiffRequest struct {
	StartRoot Root        `json:"start_root"`
	EndRoot   Root        `json:"end_root"`
	Options   SyncOptions `json:"options"`

GetDiffRequest is a GetDiff request.

type GetPrefixesRequest

type GetPrefixesRequest = syncer.GetPrefixesRequest

GetPrefixesRequest is a request for the SyncGetPrefixes operation.

type GetRequest

type GetRequest = syncer.GetRequest

GetRequest is a request for the SyncGet operation.

type InternalNode

type InternalNode = mkvsNode.InternalNode

InternalNode is an internal node with two children.

type IterateRequest

type IterateRequest = syncer.IterateRequest

IterateRequest is a request for the SyncIterate operation.

type Key

type Key = mkvsNode.Key

Key is a node's key spelled out from the root to the node.

type LeafNode

type LeafNode = mkvsNode.LeafNode

LeafNode is a leaf node containing a key/value pair.

type LocalBackend

type LocalBackend interface {

	// Apply applies a set of operations against the MKVS.  The root may refer
	// to a nil node, in which case a new root will be created.
	// The expected new root is used to check if the new root after all the
	// operations are applied already exists in the local DB.  If it does, the
	// Apply is ignored.
	Apply(ctx context.Context, request *ApplyRequest) error

	// Checkpointer returns the checkpoint creator/restorer for this storage backend.
	Checkpointer() checkpoint.CreateRestorer

	// NodeDB returns the underlying node database.
	NodeDB() nodedb.NodeDB

LocalBackend is a storage implementation with a local backing store.

type LogEntry

type LogEntry = writelog.LogEntry

LogEntry is a write log entry.

type Node

type Node = mkvsNode.Node

Node is either an InternalNode or a LeafNode.

type NodeDB

type NodeDB = nodedb.NodeDB

NodeDB is a node database.

type Pointer

type Pointer = mkvsNode.Pointer

Pointer is a pointer to another node.

type Proof

type Proof = syncer.Proof

Proof is a Merkle proof for a subtree.

type ProofResponse

type ProofResponse = syncer.ProofResponse

ProofResponse is a response for requests that produce proofs.

type Root

type Root = mkvsNode.Root

Root is a storage root.

type RootCache

type RootCache struct {
	// contains filtered or unexported fields

RootCache is a LRU based tree cache.

func NewRootCache

func NewRootCache(localDB nodedb.NodeDB) (*RootCache, error)

func (*RootCache) Apply

func (rc *RootCache) Apply(
	ctx context.Context,
	root Root,
	expectedNewRoot Root,
	writeLog WriteLog,
) (*hash.Hash, error)

Apply applies the write log, bypassing the apply operation iff the new root already is in the node database.

func (*RootCache) GetTree

func (rc *RootCache) GetTree(root Root) (mkvs.Tree, error)

GetTree gets a tree entry from the cache by the root iff present, or creates a new tree with the specified root in the node database.

func (*RootCache) HasRoot

func (rc *RootCache) HasRoot(root Root) bool

type RootType added in v0.2100.0

type RootType = mkvsNode.RootType

RootType is a storage root type.

type SyncChunk

type SyncChunk struct {
	Final    bool     `json:"final"`
	WriteLog WriteLog `json:"writelog"`

SyncChunk is a chunk of write log entries sent during GetDiff operation.

type SyncOptions

type SyncOptions struct {
	OffsetKey []byte `json:"offset_key"`
	Limit     uint64 `json:"limit"`

SyncOptions are the sync options.

type TreeID

type TreeID = syncer.TreeID

TreeID identifies a specific tree and a position within that tree.

type WrappedLocalBackend added in v0.2102.6

type WrappedLocalBackend interface {
	// Unwrap returns the underlying local storage backend.
	Unwrap() LocalBackend

WrappedLocalBackend is an interface implemented by storage backends that wrap a local storage backend in order to support unwrapping.

type WriteLog

type WriteLog = writelog.WriteLog

WriteLog is a write log.

The keys in the write log must be unique.

type WriteLogIterator

type WriteLogIterator = writelog.Iterator

WriteLogIterator iterates over write log entries.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL