Files
zeekay 7cf87b230b node-unified is the node
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.
2026-09-07 16:15:25 -07:00

334 lines
9.6 KiB
Go

// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package merkledb
import (
"cmp"
"errors"
"fmt"
"maps"
"slices"
"strings"
"unsafe"
)
var (
ErrInvalidBranchFactor = errors.New("branch factor must match one of the predefined branch factors")
BranchFactorToTokenSize = map[BranchFactor]int{
BranchFactor2: 1,
BranchFactor4: 2,
BranchFactor16: 4,
BranchFactor256: 8,
}
tokenSizeToBranchFactor = map[int]BranchFactor{
1: BranchFactor2,
2: BranchFactor4,
4: BranchFactor16,
8: BranchFactor256,
}
validTokenSizes = slices.Collect(maps.Keys(tokenSizeToBranchFactor))
validBranchFactors = []BranchFactor{
BranchFactor2,
BranchFactor4,
BranchFactor16,
BranchFactor256,
}
)
type BranchFactor int
const (
BranchFactor2 = BranchFactor(2)
BranchFactor4 = BranchFactor(4)
BranchFactor16 = BranchFactor(16)
BranchFactor256 = BranchFactor(256)
BranchFactorLargest = BranchFactor256
)
// Valid checks if BranchFactor [b] is one of the predefined valid options for BranchFactor
func (b BranchFactor) Valid() error {
if slices.Contains(validBranchFactors, b) {
return nil
}
return fmt.Errorf("%w: %d", ErrInvalidBranchFactor, b)
}
// ToToken creates a key version of the passed byte with bit length equal to tokenSize
func ToToken(val byte, tokenSize int) Key {
return Key{
value: string([]byte{val << dualBitIndex(tokenSize)}),
length: tokenSize,
}
}
// Token returns the token at the specified index,
// Assumes that bitIndex + tokenSize doesn't cross a byte boundary
func (k Key) Token(bitIndex int, tokenSize int) byte {
storageByte := k.value[bitIndex/8]
// Shift the byte right to get the last bit to the rightmost position.
storageByte >>= dualBitIndex((bitIndex + tokenSize) % 8)
// Apply a mask to remove any other bits in the byte.
return storageByte & (0xFF >> dualBitIndex(tokenSize))
}
// iteratedHasPrefix checks if the provided prefix key is a prefix of the current key starting after the [bitsOffset]th bit
// this has better performance than constructing the actual key via Skip() then calling HasPrefix because it avoids an allocation
func (k Key) iteratedHasPrefix(prefix Key, bitsOffset int, tokenSize int) bool {
if k.length-bitsOffset < prefix.length {
return false
}
for i := 0; i < prefix.length; i += tokenSize {
if k.Token(bitsOffset+i, tokenSize) != prefix.Token(i, tokenSize) {
return false
}
}
return true
}
type Key struct {
// The number of bits in the key.
length int
// The string representation of the key
value string
}
// ToKey returns [keyBytes] as a new key
// Assumes all bits of the keyBytes are part of the Key, call Key.Take if that is not the case
// Creates a copy of [keyBytes], so keyBytes are safe to edit after the call
func ToKey(keyBytes []byte) Key {
return toKey(slices.Clone(keyBytes))
}
// toKey returns [keyBytes] as a new key
// Assumes all bits of the keyBytes are part of the Key, call Key.Take if that is not the case
// Caller must not modify [keyBytes] after this call.
func toKey(keyBytes []byte) Key {
return Key{
value: byteSliceToString(keyBytes),
length: len(keyBytes) * 8,
}
}
// hasPartialByte returns true iff the key fits into a non-whole number of bytes
func (k Key) hasPartialByte() bool {
return k.length%8 > 0
}
// HasPrefix returns true iff [prefix] is a prefix of [k] or equal to it.
func (k Key) HasPrefix(prefix Key) bool {
// [prefix] must be shorter than [k] to be a prefix.
if k.length < prefix.length {
return false
}
// The number of tokens in the last byte of [prefix], or zero
// if [prefix] fits into a whole number of bytes.
remainderBitCount := prefix.length % 8
if remainderBitCount == 0 {
return strings.HasPrefix(k.value, prefix.value)
}
// check that the tokens in the partially filled final byte of [prefix] are
// equal to the tokens in the final byte of [k].
remainderBitsMask := byte(0xFF >> remainderBitCount)
prefixRemainderTokens := prefix.value[len(prefix.value)-1] | remainderBitsMask
remainderTokens := k.value[len(prefix.value)-1] | remainderBitsMask
if prefixRemainderTokens != remainderTokens {
return false
}
// Note that this will never be an index OOB because len(prefix.value) > 0.
// If len(prefix.value) == 0 were true, [remainderTokens] would be 0, so we
// would have returned above.
prefixWithoutPartialByte := prefix.value[:len(prefix.value)-1]
return strings.HasPrefix(k.value, prefixWithoutPartialByte)
}
// HasStrictPrefix returns true iff [prefix] is a prefix of [k]
// but is not equal to it.
func (k Key) HasStrictPrefix(prefix Key) bool {
return k != prefix && k.HasPrefix(prefix)
}
// Length returns the number of bits in the Key
func (k Key) Length() int {
return k.length
}
// Greater returns true if current Key is greater than other Key
func (k Key) Greater(other Key) bool {
return k.Compare(other) == 1
}
// Less will return true if current Key is less than other Key
func (k Key) Less(other Key) bool {
return k.Compare(other) == -1
}
func (k Key) Compare(other Key) int {
if valueCmp := cmp.Compare(k.value, other.value); valueCmp != 0 {
return valueCmp
}
return cmp.Compare(k.length, other.length)
}
// Extend returns a new Key that is the in-order aggregation of Key [k] with [keys]
func (k Key) Extend(keys ...Key) Key {
totalBitLength := k.length
for _, key := range keys {
totalBitLength += key.length
}
buffer := make([]byte, bytesNeeded(totalBitLength))
copy(buffer, k.value)
currentTotal := k.length
for _, key := range keys {
extendIntoBuffer(buffer, key, currentTotal)
currentTotal += key.length
}
return Key{
value: byteSliceToString(buffer),
length: totalBitLength,
}
}
func extendIntoBuffer(buffer []byte, val Key, bitsOffset int) {
if val.length == 0 {
return
}
bytesOffset := bytesNeeded(bitsOffset)
bitsRemainder := bitsOffset % 8
if bitsRemainder == 0 {
copy(buffer[bytesOffset:], val.value)
return
}
// Fill the partial byte with the first [shift] bits of the extension path
buffer[bytesOffset-1] |= val.value[0] >> bitsRemainder
// copy the rest of the extension path bytes into the buffer,
// shifted byte shift bits
shiftCopy(buffer[bytesOffset:], val.value, dualBitIndex(bitsRemainder))
}
// dualBitIndex gets the dual of the bit index
// ex: in a byte, the bit 5 from the right is the same as the bit 3 from the left
func dualBitIndex(shift int) int {
return (8 - shift) % 8
}
// Treats [src] as a bit array and copies it into [dst] shifted by [shift] bits.
// For example, if [src] is [0b0000_0001, 0b0000_0010] and [shift] is 4,
// we copy [0b0001_0000, 0b0010_0000] into [dst].
// Assumes len(dst) >= len(src)-1.
// If len(dst) == len(src)-1 the last byte of [src] is only partially copied
// (i.e. the rightmost bits are not copied).
func shiftCopy(dst []byte, src string, shift int) {
i := 0
dualShift := dualBitIndex(shift)
for ; i < len(src)-1; i++ {
dst[i] = src[i]<<shift | src[i+1]>>dualShift
}
if i < len(dst) {
// the last byte only has values from byte i, as there is no byte i+1
dst[i] = src[i] << shift
}
}
// Skip returns a new Key that contains the last
// k.length-bitsToSkip bits of [k].
func (k Key) Skip(bitsToSkip int) Key {
if k.length <= bitsToSkip {
return Key{}
}
result := Key{
value: k.value[bitsToSkip/8:],
length: k.length - bitsToSkip,
}
// if the tokens to skip is a whole number of bytes,
// the remaining bytes exactly equals the new key.
if bitsToSkip%8 == 0 {
return result
}
// bitsToSkip does not remove a whole number of bytes.
// copy the remaining shifted bytes into a new buffer.
buffer := make([]byte, bytesNeeded(result.length))
bitsRemovedFromFirstRemainingByte := bitsToSkip % 8
shiftCopy(buffer, result.value, bitsRemovedFromFirstRemainingByte)
result.value = byteSliceToString(buffer)
return result
}
// Take returns a new Key that contains the first bitsToTake bits of the current Key
func (k Key) Take(bitsToTake int) Key {
if k.length <= bitsToTake {
return k
}
result := Key{
length: bitsToTake,
}
remainderBits := result.length % 8
if remainderBits == 0 {
result.value = k.value[:bitsToTake/8]
return result
}
// We need to zero out some bits of the last byte so a simple slice will not work
// Create a new []byte to store the altered value
buffer := make([]byte, bytesNeeded(bitsToTake))
copy(buffer, k.value)
// We want to zero out everything to the right of the last token, which is at index bitsToTake-1
// Mask will be (8-remainderBits) number of 1's followed by (remainderBits) number of 0's
buffer[len(buffer)-1] &= byte(0xFF << dualBitIndex(remainderBits))
result.value = byteSliceToString(buffer)
return result
}
// Bytes returns the raw bytes of the Key
// Invariant: The returned value must not be modified.
func (k Key) Bytes() []byte {
// avoid copying during the conversion
// "safe" because we never edit the value, only used as DB key
return stringToByteSlice(k.value)
}
// byteSliceToString converts the []byte to a string
// Invariant: The input []byte must not be modified.
func byteSliceToString(bs []byte) string {
// avoid copying during the conversion
// "safe" because we never edit the []byte, and it is never returned by any functions except Bytes()
return unsafe.String(unsafe.SliceData(bs), len(bs))
}
// stringToByteSlice converts the string to a []byte
// Invariant: The output []byte must not be modified.
func stringToByteSlice(value string) []byte {
// avoid copying during the conversion
// "safe" because we never edit the []byte
return unsafe.Slice(unsafe.StringData(value), len(value))
}
// Returns the number of bytes needed to store [bits] bits.
func bytesNeeded(bits int) int {
size := bits / 8
if bits%8 != 0 {
size++
}
return size
}