tag

package
v0.0.0-...-43ed5bc Latest Latest
Warning

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

Go to latest
Published: Feb 25, 2026 License: Apache-2.0 Imports: 20 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DecodableKeyHashToString

func DecodableKeyHashToString(dkh DecodableKeyHash) string

DecodableKeyHashToString converts a tag's key hash including its decoding parameters to a string representations.

TODO: Maybe this function should not exist, and we should only provide a version that converts a model_core.Decodable[tag.Key] to a string? Including the signature public key in the output would be necessary for linking to pages like bonanza_browser.

func ResolveDecodableTag

func ResolveDecodableTag[TReference any](
	ctx context.Context,
	resolver BoundResolver[TReference],
	keyHash DecodableKeyHash,
) (model_core.Decodable[TReference], error)

ResolveDecodableTag resolves the reference associated with a tag using a BoundResolver. In addition to that, it copies the decoding parameters that are attached to a key hash to the resulting reference. This allows the referenced object to be read using model_parser.DecodingObjectReader.

Types

type BoundResolver

type BoundResolver[TReference any] interface {
	ResolveTag(ctx context.Context, keyHash [sha256.Size]byte) (TReference, error)
}

BoundResolver can be used to resolve references that are associated with tags. It differs from Resolver in pkg/storage/tag as follows:

  • It is bound to a specific storage namespace.
  • It is bound to a given public key. The caller only needs to provide the key's hash.
  • Only references to complete graphs are returned.
  • References can be of an arbitrary type, instead of just object.LocalReference as contained in tag.SignedValue.

func NewObjectImportingBoundResolver

func NewObjectImportingBoundResolver[TInternal, TExternal any](base BoundResolver[TExternal], objectExporter model_core.ObjectExporter[TInternal, TExternal]) BoundResolver[TInternal]

NewObjectImportingBoundResolver creates a decorator for BoundResolver that converts the references it obtained from its backend to another format, using an ObjectExporter. This can, for example, be used to convert instances of object.LocalReference to ones that are buffered.

func NewStorageBackedBoundResolver

func NewStorageBackedBoundResolver(resolver tag.Resolver[struct{}], signaturePublicKey [ed25519.PublicKeySize]byte) BoundResolver[object.LocalReference]

NewStorageBackedBoundResolver creates a basic implementation of BoundResolver that calls into a storage backend.

type BoundStore

type BoundStore[TReference any] interface {
	BoundResolver[TReference]
	BoundUpdater[TReference]
}

BoundStore is a store for tags, which is both accessible for reading (resolving) and writing (updating). Differences from Store in pkg/storage tag include:

  • It is bound to a specific storage namespace.
  • It is bound to a given key pair. The caller only needs to provide the key's hash.
  • References can be of an arbitrary type, instead of just object.LocalReference as contained in tag.SignedValue.

func NewBoundStore

func NewBoundStore[TReference any](resolver BoundResolver[TReference], updater BoundUpdater[TReference]) BoundStore[TReference]

NewBoundStore is a helper function for creating a BoundStore that is backed by separate instances of BoundResolver and BoundUpdater.

type BoundUpdater

type BoundUpdater[TReference any] interface {
	UpdateTag(ctx context.Context, keyHash [sha256.Size]byte, reference TReference) error
}

BoundUpdater can be used to update references that are associated with tags. It differs from Updater in pkg/storage/tag as follows:

  • It is bound to a specific storage namespace.
  • It is bound to a given private key. The caller only needs to provide the key's hash.
  • The timestamp embedded in the tag's value will also be set to the current time of day.
  • References can be of an arbitrary type, instead of just object.LocalReference as contained in tag.SignedValue.

type DAGUploaderForTesting

type DAGUploaderForTesting dag.Uploader[struct{}, object.LocalReference]

DAGUploaderForTesting is used to generate mocks used by tests belonging to this package.

type DecodableKeyHash

type DecodableKeyHash = model_core.Decodable[[sha256.Size]byte]

DecodableKeyHash contains a key hash that can be used to look up a tag in Tag Store. It also contains the decoding parameters that are needed to decode any objects referenced by it.

func NewDecodableKeyHashFromMessage

func NewDecodableKeyHashFromMessage[TMessage proto.Message, TReference object.BasicReference](
	m model_core.TopLevelMessage[TMessage, TReference],
	decodingParametersSizeBytes int,
) (DecodableKeyHash, error)

NewDecodableKeyHashFromMessage computes a key hash of a tag, using a Protobuf message as an input. The message is first wrapped in a google.protobuf.Any to ensure there are no collisions in case different message types are used.

Normally when encrypted objects are created, the encoding process yields decoding parameters that need to be stored in the encrypted payload of the parent object. This ensures that even when the encryption key is divulged, access to payloads of objects is restricted to ones belonging graphs to which the user has access.

The issue is that the concept of decoding parameters is specific to the data model we build on top of the Object Store. The Object Store itself is oblivious of them. The same holds for the Tag Store, which is only capable of storing plain references to objects, which don't include decoding parameters.

In order to decode objects referenced by tags, we let the decoding parameters be based on the hash in the tag's key. However, we do not want them to be directly derivable from the hash, as that would allow anyone capable of iterating tags in storage to decrypt all objects once the key is divulged.

To solve this, we compute a SHA-512 hash of the message. The first half of the resulting SHA-512 hash is used as the tag key hash at the storage level. The other half is used as the decoding parameters. This means that tags can only be resolved and the referenced object decoded if the original tag key hash is known.

type MessageObjectReaderForTesting

MessageObjectReaderForTesting is used to generate mocks used by tests belonging to this package.

type MutableProtoHandle

type MutableProtoHandle[T proto.Message] interface {
	GetMutableProto() T
	Release(isDirty bool)
}

MutableProtoHandle is a handle that is returned by MutableProtoStore. It contains a MutableProto message that contains timing information of previous executions of similar actions.

type MutableProtoStore

type MutableProtoStore[T proto.Message] interface {
	Get(ctx context.Context, tagKeyHash DecodableKeyHash) (MutableProtoHandle[T], error)
}

MutableProtoStore is a store for Protobuf messages, allowing them both to be read and written. Because multiple operations may interact with a single Protobuf message, this interface permits concurrent access to the same message.

The Get() function may be called in parallel, yielding a MutableProtoHandle. Because these handles are shared, all methods on all handles obtained from a single store must be called while holding a global lock. The Protobuf message embedded in the handle gets invalidated after locks are dropped.

func NewStorageBackedMutableProtoStore

func NewStorageBackedMutableProtoStore[T any, TProto interface {
	*T
	proto.Message
}](
	referenceFormat object.ReferenceFormat,
	tagResolver tag.Resolver[struct{}],
	tagSignaturePrivateKey ed25519.PrivateKey,
	messageObjectReader model_parser.MessageObjectReader[object.LocalReference, TProto],
	objectEncoder model_encoding.KeyedBinaryEncoder,
	dagUploader dag.Uploader[struct{}, object.LocalReference],
	clock clock.Clock,
) MutableProtoStore[TProto]

NewStorageBackedMutableProtoStore creates an instance of MutableProtoStore that is backed by Object Store and Tag Store.

What makes this interface harder to implement is that releasing MutableProtoHandle is performed while holding locks. We can't block, nor can we propagate errors or perform retries. To solve this, this implementation keeps track of a list of all handles that need to be written. Every time a handle is created, we write a couple of released handles back to storage. This ensures that the number of handles remains proportional to actual use.

type ResolverForTesting

type ResolverForTesting tag.Resolver[struct{}]

ResolverForTesting is used to generate mocks used by tests belonging to this package.

Jump to

Keyboard shortcuts

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