Documentation
¶
Overview ¶
Package oplog implements OrbitDB's operation log: an append-only, signed Merkle-CRDT of entries.
It is a port of src/oplog in @orbitdb/core 4. Entries are byte-compatible with the JavaScript implementation, and the algorithms that decide entry contents (heads, references, traversal order, conflict resolution) follow it exactly, so a Go and a JavaScript peer appending the same operations produce the same hashes.
Index ¶
- Constants
- func CompareClocks(a, b Clock) int
- func EncodeEntry(ctx context.Context, entry *Entry, enc Encryption) (hash string, data []byte, err error)
- func IsEntry(entry *Entry) bool
- func IsEqual(a, b *Entry) bool
- func LastWriteWins(a, b *Entry) int
- func SortByClockID(a, b *Entry, resolveConflict SortFn) int
- func SortByClocks(a, b *Entry, resolveConflict SortFn) int
- func VerifyEntry(entry *Entry) (bool, error)
- type AccessController
- type AppendOptions
- type Clock
- type Encrypter
- type Encryption
- type Entry
- type EntryOptions
- type IteratorOptions
- type Log
- func (l *Log) AccessController() AccessController
- func (l *Log) Append(ctx context.Context, payload any, opts AppendOptions) (*Entry, error)
- func (l *Log) Clear(ctx context.Context) error
- func (l *Log) Clock(ctx context.Context) (Clock, error)
- func (l *Log) Close() error
- func (l *Log) Encryption() Encryption
- func (l *Log) Get(ctx context.Context, hash string) (*Entry, error)
- func (l *Log) Has(ctx context.Context, hash string) (bool, error)
- func (l *Log) Heads(ctx context.Context) ([]*Entry, error)
- func (l *Log) ID() string
- func (l *Log) Identity() *identitytypes.Identity
- func (l *Log) Iterator(ctx context.Context, opts IteratorOptions) iter.Seq2[*Entry, error]
- func (l *Log) Join(ctx context.Context, other *Log) error
- func (l *Log) JoinEntry(ctx context.Context, entry *Entry) (bool, error)
- func (l *Log) Storage() storage.Storage
- func (l *Log) Traverse(ctx context.Context, roots []*Entry, shouldStop func(*Entry) (bool, error)) iter.Seq2[*Entry, error]
- func (l *Log) Values(ctx context.Context) ([]*Entry, error)
- type Options
- type SortFn
Constants ¶
const EntryVersion = 2
EntryVersion is the version tag of the entry format ("v" field).
Variables ¶
This section is empty.
Functions ¶
func CompareClocks ¶
CompareClocks orders clocks by time and, for concurrent clocks with different ids, by id. The result is negative when a is less than b and positive when it is greater; it is zero only when a and b are the same clock.
func EncodeEntry ¶
func EncodeEntry(ctx context.Context, entry *Entry, enc Encryption) (hash string, data []byte, err error)
EncodeEntry returns the hash and bytes of the block entry is stored as.
func LastWriteWins ¶
LastWriteWins orders entries by clock time, then by clock id. Entries with identical clocks compare equal and keep their relative order.
func SortByClockID ¶
SortByClockID orders entries by clock id and calls resolveConflict for entries with the same clock id.
func SortByClocks ¶
SortByClocks orders entries by clock and calls resolveConflict for entries with identical clocks.
func VerifyEntry ¶
VerifyEntry reports whether the entry's signature was made by the key in entry.Key. It does not check that the key belongs to entry.Identity; an access controller does that.
Types ¶
type AccessController ¶
AccessController decides who may write to a log. It is consulted for every appended entry and for every entry joined from a peer, after the entry's signature has been checked.
func AllowAll ¶
func AllowAll() AccessController
AllowAll returns an AccessController that accepts every entry.
type AppendOptions ¶
type AppendOptions struct {
// ReferencesCount is how many entries beyond the heads the new entry
// refers to, so readers can skip ahead when traversing.
ReferencesCount int
}
AppendOptions configures Log.Append.
type Clock ¶
Clock is a Lamport clock. ID is the public key of the writer that produced the entry, Time its logical time.
type Encrypter ¶
type Encrypter interface {
Encrypt(ctx context.Context, plaintext []byte) ([]byte, error)
Decrypt(ctx context.Context, ciphertext []byte) ([]byte, error)
}
Encrypter encrypts and decrypts bytes. An implementation is given to a log through Encryption.
type Encryption ¶
type Encryption struct {
// Replication encrypts whole entry blocks, so storage and the network
// only see ciphertext. The stored block is the dag-cbor byte string of
// the ciphertext.
Replication Encrypter
// Data encrypts entry payloads. The payload is encoded as dag-cbor,
// encrypted, and the ciphertext is what gets signed and stored.
Data Encrypter
}
Encryption configures the optional encryption hooks of @orbitdb/core 4. Both are off when nil.
type Entry ¶
type Entry struct {
// ID is the id of the log the entry belongs to.
ID string
// Payload is any value dag-cbor can encode; see package block for the
// Go types it maps to.
Payload any
// Next holds the hashes of the log heads the entry was appended on.
Next []string
// Refs holds hashes of older entries, to speed up traversal.
Refs []string
Clock Clock
V int64
// Key is the public key of the writer's identity.
Key string
// Identity is the hash of the writer's identity block.
Identity string
// Sig is the writer's signature of the entry.
Sig string
// Hash is the base58btc CID of the stored entry block. It is set once
// the entry has been stored or decoded.
Hash string
// contains filtered or unexported fields
}
Entry is a signed, content-addressed log entry.
Its dag-cbor encoding is byte-compatible with @orbitdb/core 4: the map {id, payload, next, refs, clock: {id, time}, v, key, identity, sig}, where sig signs the encoding of the first six fields.
func CreateEntry ¶
func CreateEntry(ctx context.Context, identity *identitytypes.Identity, logID string, payload any, opts EntryOptions) (*Entry, error)
CreateEntry creates and signs an entry for log logID. The entry is not stored; its Hash is empty until it is.
func DecodeEntry ¶
DecodeEntry parses an entry block, decrypting it if enc says so. The returned entry's Hash is the CID of data.
type EntryOptions ¶
type EntryOptions struct {
// Clock of the entry. Defaults to time 0 on the identity's public key.
Clock *Clock
Next []string
Refs []string
// EncryptPayload, if set, encrypts the payload (see Encryption.Data).
EncryptPayload Encrypter
}
EntryOptions configures CreateEntry.
type IteratorOptions ¶
type IteratorOptions struct {
// Amount limits the number of entries. Zero or negative means all.
Amount int
// GT and GTE end the iteration at an entry, excluding or including it.
GT, GTE string
// LT and LTE start the iteration at an entry, excluding or including
// it.
LT, LTE string
}
IteratorOptions selects a range of entries for Log.Iterator. Ranges are given by entry hash and follow the traversal order (newest first).
type Log ¶
type Log struct {
// contains filtered or unexported fields
}
Log is an append-only log of signed entries.
func (*Log) AccessController ¶
func (l *Log) AccessController() AccessController
AccessController returns the log's access controller.
func (*Log) Append ¶
Append signs payload into a new entry on top of the current heads and makes it the only head.
func (*Log) Clock ¶
Clock returns the log's clock: the writer's public key at the latest time among the heads.
func (*Log) Encryption ¶
func (l *Log) Encryption() Encryption
Encryption returns the log's encryption settings.
func (*Log) Get ¶
Get returns the entry with the given hash. It returns an error wrapping storage.ErrNotFound if the entry is not stored.
func (*Log) Identity ¶
func (l *Log) Identity() *identitytypes.Identity
Identity returns the identity the log appends as.
func (*Log) Join ¶
Join merges other into this log: other's entry blocks are copied into this log's entry storage and each of its heads is joined.
func (*Log) JoinEntry ¶
JoinEntry adds an entry received from a peer, together with every ancestor the log does not have yet. Each new entry must belong to the log, pass the access controller and carry a valid signature. Ancestors are read from the entry storage, which fetches them from peers when it is backed by IPFS. It reports whether the log changed.
func (*Log) Traverse ¶
func (l *Log) Traverse(ctx context.Context, roots []*Entry, shouldStop func(*Entry) (bool, error)) iter.Seq2[*Entry, error]
Traverse walks the log from roots (the current heads when nil), yielding each reachable entry once, latest first according to the sort function. If shouldStop is set it is called after each yielded entry and ends the walk when it returns true. Entries missing from storage are skipped.
type Options ¶
type Options struct {
// LogID identifies the log; entries of other logs cannot be joined.
// Defaults to the current Unix time in milliseconds.
LogID string
// LogHeads, if set, replaces the persisted heads.
LogHeads []*Entry
// AccessController decides who may write. Defaults to AllowAll.
AccessController AccessController
// EntryStorage holds entry blocks, IndexStorage records which entries
// are part of the log and HeadsStorage the current heads. Each
// defaults to a MemoryStorage.
EntryStorage storage.Storage
HeadsStorage storage.Storage
IndexStorage storage.Storage
// SortFn orders concurrent entries. Defaults to LastWriteWins.
SortFn SortFn
// Encryption turns on entry and/or payload encryption.
Encryption Encryption
}
Options configures NewLog.