mirror of
https://github.com/luxfi/node.git
synced 2026-10-30 15:24:05 +00:00
The module already called itself github.com/luxfi/node while containing no node in Go: cmd/luxd was twenty-one lines that printed the size of a few types, and the Go column of the matrix measured a VM plugin. A repo that fetches the thing it claims to be has not replaced it, so the Go sources move in — 1515 files, the daemon and everything under it — and the build reaches outside this module for nothing. Rust and C++ sit beside it unchanged and are still measured against it by the differential. That is the point of one repo: the reference implementation and the two ports are the same checkout, so parity is a thing you can run rather than a thing you assert. Verified: builds, and the closure carries no lux-private — checked at build time rather than believed. The daemon starts twelve chains on a local network (P X C Q Z A B G K M F, plus D through its plugin) and reports healthy.
106 lines
2.9 KiB
Go
106 lines
2.9 KiB
Go
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package archivedb
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"io"
|
|
|
|
"github.com/luxfi/database"
|
|
"github.com/luxfi/node/service/health"
|
|
)
|
|
|
|
var (
|
|
ErrNotImplemented = errors.New("feature not implemented")
|
|
ErrInvalidValue = errors.New("invalid data value")
|
|
|
|
_ database.Compacter = (*Database)(nil)
|
|
_ health.Checker = (*Database)(nil)
|
|
_ io.Closer = (*Database)(nil)
|
|
)
|
|
|
|
// Database implements an ArchiveDB on top of a database.Database. An ArchiveDB
|
|
// is an append only database which stores all state changes happening at every
|
|
// height. Each record is stored in such way to perform both fast insertions and
|
|
// lookups.
|
|
//
|
|
// The API is quite simple, it has two main functions, one to create a Batch
|
|
// write with a given height, inside this batch entries can be added with a
|
|
// given value or they can be deleted.
|
|
//
|
|
// The way it works is as follows:
|
|
// - NewBatch(10)
|
|
// batch.Put(foo, "foo's value is bar")
|
|
// batch.Put(bar, "bar's value is bar")
|
|
// - NewBatch(100)
|
|
// batch.Put(foo, "updatedfoo's value is bar")
|
|
// - NewBatch(1000)
|
|
// batch.Put(bar, "updated bar's value is bar")
|
|
// batch.Delete(foo)
|
|
//
|
|
// The other primary function is to read data at a given height.
|
|
//
|
|
// The way it works is as follows:
|
|
// - Open(10)
|
|
// reader.Get(foo)
|
|
// reader.Get(bar)
|
|
// - Open(99)
|
|
// reader.GetHeight(foo)
|
|
// - Open(100)
|
|
// reader.Get(foo)
|
|
// - Open(1000)
|
|
// reader.Get(foo)
|
|
//
|
|
// Requesting `reader.Get(foo)` at height 1000 will return ErrNotFound because
|
|
// foo was deleted at height 1000. When calling `reader.GetHeight(foo)` at
|
|
// height 99 it will return a tuple `("foo's value is bar", 10)` returning the
|
|
// value of `foo` at height 99 (which was set at height 10).
|
|
type Database struct {
|
|
db database.Database
|
|
}
|
|
|
|
func New(db database.Database) *Database {
|
|
return &Database{
|
|
db: db,
|
|
}
|
|
}
|
|
|
|
// Height returns the last written height.
|
|
func (db *Database) Height() (uint64, error) {
|
|
return database.GetUInt64(db.db, heightKey)
|
|
}
|
|
|
|
// Open returns a reader for the state at the given height.
|
|
func (db *Database) Open(height uint64) *Reader {
|
|
return &Reader{
|
|
db: db,
|
|
height: height,
|
|
}
|
|
}
|
|
|
|
// NewBatch creates a write batch to perform changes at a given height.
|
|
//
|
|
// Note: Committing multiple batches at the same height, or at a lower height
|
|
// than the currently committed height will not error. It is left up to the
|
|
// caller to enforce any guarantees they need around height consistency.
|
|
func (db *Database) NewBatch(height uint64) *batch {
|
|
return &batch{
|
|
db: db,
|
|
height: height,
|
|
}
|
|
}
|
|
|
|
func (db *Database) Compact(start []byte, limit []byte) error {
|
|
return db.db.Compact(start, limit)
|
|
}
|
|
|
|
func (db *Database) HealthCheck(ctx context.Context) (interface{}, error) {
|
|
return db.db.HealthCheck(ctx)
|
|
}
|
|
|
|
func (db *Database) Close() error {
|
|
return db.db.Close()
|
|
}
|