Documentation
¶
Overview ¶
Package api implements the storage backend API.
Index ¶
- Constants
- Variables
- func NodePriorityHintFromContext(ctx context.Context) []signature.PublicKey
- func RegisterService(server *grpc.Server, service Backend)
- func WithNodePriorityHint(ctx context.Context, nodes []signature.PublicKey) context.Context
- func WithNodePriorityHintFromMap(ctx context.Context, nodes map[signature.PublicKey]bool) context.Context
- func WithNodePriorityHintFromSignatures(ctx context.Context, sigs []signature.Signature) context.Context
- type ApplyBatchRequest
- type ApplyOp
- type ApplyRequest
- type Backend
- type ClientBackend
- type Config
- type Depth
- type GetDiffRequest
- type GetPrefixesRequest
- type GetRequest
- type InternalNode
- type IterateRequest
- type Key
- type LeafNode
- type LocalBackend
- type LogEntry
- type Node
- type NodeDB
- type Pointer
- type Proof
- type ProofResponse
- type Receipt
- type ReceiptBody
- type Root
- type RootCache
- type SyncChunk
- type SyncOptions
- type TreeID
- type WriteLog
- type WriteLogIterator
Constants ¶
const ( // ModuleName is the storage module name. ModuleName = "storage" // WriteLogIteratorChunkSize defines the chunk size of write log entries // for the GetDiff method. WriteLogIteratorChunkSize = 10 )
Variables ¶
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 // ReceiptSignatureContext is the signature context used for verifying MKVS receipts. ReceiptSignatureContext = signature.NewContext("oasis-core/storage: receipt", signature.WithChainSeparation()) )
var ( // ServiceName is the gRPC service name. ServiceName = cmnGrpc.NewServiceName("Storage") // MethodSyncGet is the SyncGet method. MethodSyncGet = ServiceName.NewMethod("SyncGet", GetRequest{}) // MethodSyncGetPrefixes is the SyncGetPrefixes method. MethodSyncGetPrefixes = ServiceName.NewMethod("SyncGetPrefixes", GetPrefixesRequest{}) // MethodSyncIterate is the SyncIterate method. MethodSyncIterate = ServiceName.NewMethod("SyncIterate", IterateRequest{}) // MethodApply is the Apply method. MethodApply = ServiceName.NewMethod("Apply", ApplyRequest{}). WithNamespaceExtractor(func(ctx context.Context, req interface{}) (common.Namespace, error) { r, ok := req.(*ApplyRequest) if !ok { return common.Namespace{}, errInvalidRequestType } return r.Namespace, nil }). WithAccessControl(func(ctx context.Context, req interface{}) (bool, error) { return true, nil }) // MethodApplyBatch is the ApplyBatch method. MethodApplyBatch = ServiceName.NewMethod("ApplyBatch", ApplyBatchRequest{}). WithNamespaceExtractor(func(ctx context.Context, req interface{}) (common.Namespace, error) { r, ok := req.(*ApplyBatchRequest) if !ok { return common.Namespace{}, errInvalidRequestType } return r.Namespace, nil }). WithAccessControl(func(ctx context.Context, req interface{}) (bool, error) { return true, nil }) // MethodGetDiff is the GetDiff method. MethodGetDiff = ServiceName.NewMethod("GetDiff", GetDiffRequest{}). WithNamespaceExtractor(func(ctx context.Context, req interface{}) (common.Namespace, error) { r, ok := req.(*GetDiffRequest) if !ok { return common.Namespace{}, errInvalidRequestType } return r.StartRoot.Namespace, nil }). WithAccessControl(func(ctx context.Context, req interface{}) (bool, error) { return true, nil }) // MethodGetCheckpoints is the GetCheckpoints method. MethodGetCheckpoints = ServiceName.NewMethod("GetCheckpoints", checkpoint.GetCheckpointsRequest{}). WithNamespaceExtractor(func(ctx context.Context, req interface{}) (common.Namespace, error) { r, ok := req.(*checkpoint.GetCheckpointsRequest) if !ok { return common.Namespace{}, errInvalidRequestType } return r.Namespace, nil }). WithAccessControl(func(ctx context.Context, req interface{}) (bool, error) { return true, nil }) // MethodGetCheckpointChunk is the GetCheckpointChunk method. MethodGetCheckpointChunk = ServiceName.NewMethod("GetCheckpointChunk", checkpoint.ChunkMetadata{}). WithNamespaceExtractor(func(ctx context.Context, req interface{}) (common.Namespace, error) { cm, ok := req.(*checkpoint.ChunkMetadata) if !ok { return common.Namespace{}, errInvalidRequestType } return cm.Root.Namespace, nil }). WithAccessControl(func(ctx context.Context, req interface{}) (bool, error) { return true, nil }) )
Functions ¶
func NodePriorityHintFromContext ¶ added in v0.2012.3
NodePriorityHintFromContext returns the storage node priority hint or nil if none is set.
func RegisterService ¶
RegisterService registers a new sentry service with the given gRPC server.
func WithNodePriorityHint ¶ added in v0.2012.3
WithNodePriorityHint sets a storage node priority hint for any storage read requests using this context. Only storage nodes that overlap with the configured committee will be used.
func WithNodePriorityHintFromMap ¶ added in v0.2012.3
func WithNodePriorityHintFromMap(ctx context.Context, nodes map[signature.PublicKey]bool) context.Context
WithNodePriorityHintFromMap sets a storage node priority hint for any storage read requests using this context. Only storage nodes that overlap with the configured committee will be used.
func WithNodePriorityHintFromSignatures ¶ added in v0.2012.3
func WithNodePriorityHintFromSignatures(ctx context.Context, sigs []signature.Signature) context.Context
WithNodePriorityHintFromSignatures sets a storage node priority hint for any storage read requests using this context. Only storage nodes that overlap with the configured committee will be used.
Types ¶
type ApplyBatchRequest ¶
type ApplyBatchRequest struct {
Namespace common.Namespace `json:"namespace"`
DstRound uint64 `json:"dst_round"`
Ops []ApplyOp `json:"ops"`
}
ApplyBatchRequest is an ApplyBatch request.
type ApplyOp ¶
type ApplyOp struct {
// SrcRound is the source root round.
SrcRound uint64 `json:"src_round"`
// SrcRoot is the merkle root to apply the operations against. It may
// refer to a nil node (empty hash) in which case a new root will be
// created.
SrcRoot hash.Hash `json:"src_root"`
// DstRoot is the expected merkle root after applying the write log.
DstRoot hash.Hash `json:"dst_root"`
// WriteLog is a write log of operations to apply.
WriteLog WriteLog `json:"writelog"`
}
ApplyOp is an apply operation within a batch of apply operations.
type ApplyRequest ¶
type ApplyRequest struct {
Namespace common.Namespace `json:"namespace"`
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 {
syncer.ReadSyncer
checkpoint.ChunkProvider
// 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) ([]*Receipt, error)
// ApplyBatch applies multiple sets of operations against the MKVS and
// returns a single receipt covering all applied roots.
//
// See Apply for more details.
ApplyBatch(ctx context.Context, request *ApplyBatchRequest) ([]*Receipt, error)
// 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.
Cleanup()
// 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 NewStorageClient ¶
func NewStorageClient(c *grpc.ClientConn) Backend
NewStorageClient creates a new gRPC storage client service.
type ClientBackend ¶
type ClientBackend interface {
Backend
// 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
// Signer is the signing key to use for generating recipts.
Signer signature.Signer
// ApplyLockLRUSlots is the number of LRU slots to use for Apply call locks.
ApplyLockLRUSlots uint64
// InsecureSkipChecks bypasses the known root checks.
InsecureSkipChecks bool
// 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.
type 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 LocalBackend ¶
type LocalBackend interface {
Backend
// 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.
func NewMetricsWrapper ¶ added in v0.2012.3
func NewMetricsWrapper(base Backend) LocalBackend
type ProofResponse ¶
type ProofResponse = syncer.ProofResponse
ProofResponse is a response for requests that produce proofs.
type Receipt ¶
Receipt is a signed ReceiptBody.
func SignReceipt ¶
func SignReceipt(signer signature.Signer, ns common.Namespace, round uint64, roots []hash.Hash) (*Receipt, error)
SignReceipt signs a storage receipt for the given roots.
func (*Receipt) Open ¶
func (s *Receipt) Open(receipt *ReceiptBody) error
Open first verifies the blob signature then unmarshals the blob.
type ReceiptBody ¶
type ReceiptBody struct {
// Version is the storage data structure version.
Version uint16 `json:"version"`
// Namespace is the chain namespace under which the root(s) are stored.
Namespace common.Namespace `json:"ns"`
// Round is the chain round in which the root(s) are stored.
Round uint64 `json:"round"`
// Roots are the merkle roots of the merklized data structure that the
// storage node is certifying to store.
Roots []hash.Hash `json:"roots"`
}
ReceiptBody is the body of a receipt.
type RootCache ¶
type RootCache struct {
// contains filtered or unexported fields
}
RootCache is a LRU based tree cache.
func NewRootCache ¶
func (*RootCache) Apply ¶
func (rc *RootCache) Apply( ctx context.Context, ns common.Namespace, srcVersion uint64, srcRoot hash.Hash, dstVersion uint64, dstRoot hash.Hash, writeLog WriteLog, ) (*hash.Hash, error)
Apply applies the write log, bypassing the apply operation iff the new root already is in the node database.
type SyncOptions ¶
SyncOptions are the sync options.
type WriteLogIterator ¶
WriteLogIterator iterates over write log entries.