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

176 lines
5.3 KiB
Go

// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package indexer
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/luxfi/database/memdb"
"github.com/luxfi/ids"
"github.com/luxfi/log"
"github.com/luxfi/math/set"
"github.com/luxfi/runtime"
"github.com/luxfi/timer/mockable"
"github.com/luxfi/util"
)
// testRuntime creates a minimal runtime.Runtime for testing
func testRuntime(chainID ids.ID) *runtime.Runtime {
return &runtime.Runtime{
NetworkID: 1,
ChainID: chainID,
NodeID: ids.GenerateTestNodeID(),
}
}
func TestIndex(t *testing.T) {
// Setup
pageSize := uint64(64)
require := require.New(t)
baseDB := memdb.New()
// Use a test chain ID
testChainID := ids.GenerateTestID()
rt := testRuntime(testChainID)
idx, err := newIndex(baseDB, log.NoLog{}, &mockable.Clock{})
require.NoError(err)
// Populate "containers" with random IDs/bytes
containers := map[ids.ID][]byte{}
for i := uint64(0); i < 2*pageSize; i++ {
containers[ids.GenerateTestID()] = utils.RandomBytes(32)
}
// Accept each container and after each, make assertions
i := uint64(0)
for containerID, containerBytes := range containers {
require.NoError(idx.Accept(rt, containerID, containerBytes))
lastAcceptedIndex, ok := idx.lastAcceptedIndex()
require.True(ok)
require.Equal(i, lastAcceptedIndex)
require.Equal(i+1, idx.nextAcceptedIndex)
gotContainer, err := idx.GetContainerByID(containerID)
require.NoError(err)
require.Equal(containerBytes, gotContainer.Bytes)
gotIndex, err := idx.GetIndex(containerID)
require.NoError(err)
require.Equal(i, gotIndex)
gotContainer, err = idx.GetContainerByIndex(i)
require.NoError(err)
require.Equal(containerBytes, gotContainer.Bytes)
gotContainer, err = idx.GetLastAccepted()
require.NoError(err)
require.Equal(containerBytes, gotContainer.Bytes)
containers, err := idx.GetContainerRange(i, 1)
require.NoError(err)
require.Len(containers, 1)
require.Equal(containerBytes, containers[0].Bytes)
containers, err = idx.GetContainerRange(i, 2)
require.NoError(err)
require.Len(containers, 1)
require.Equal(containerBytes, containers[0].Bytes)
i++
}
// Create a new index with the same database and ensure contents still there
require.NoError(idx.vDB.Commit())
// Create a new index by directly using the same base database
// Don't close the old index to avoid closing the baseDB
idx, err = newIndex(baseDB, log.NoLog{}, &mockable.Clock{})
require.NoError(err)
// Get all of the containers
containersList, err := idx.GetContainerRange(0, pageSize)
require.NoError(err)
require.Len(containersList, int(pageSize))
containersList2, err := idx.GetContainerRange(pageSize, pageSize)
require.NoError(err)
require.Len(containersList2, int(pageSize))
containersList = append(containersList, containersList2...)
// Ensure that the data is correct
lastTimestamp := int64(0)
sawContainers := make(set.Set[ids.ID])
for _, container := range containersList {
require.False(sawContainers.Contains(container.ID)) // Should only see this container once
require.Contains(containers, container.ID)
require.Equal(containers[container.ID], container.Bytes)
// Timestamps should be non-decreasing
require.GreaterOrEqual(container.Timestamp, lastTimestamp)
lastTimestamp = container.Timestamp
sawContainers.Add(container.ID)
}
}
func TestIndexGetContainerByRangeMaxPageSize(t *testing.T) {
// Setup
require := require.New(t)
db := memdb.New()
// Use a test chain ID
testChainID := ids.GenerateTestID()
rt := testRuntime(testChainID)
idx, err := newIndex(db, log.NoLog{}, &mockable.Clock{})
require.NoError(err)
// Insert [MaxFetchedByRange] + 1 containers
for i := uint64(0); i < MaxFetchedByRange+1; i++ {
require.NoError(idx.Accept(rt, ids.GenerateTestID(), utils.RandomBytes(32)))
}
// Page size too large
_, err = idx.GetContainerRange(0, MaxFetchedByRange+1)
require.ErrorIs(err, errNumToFetchInvalid)
// Make sure data is right
containers, err := idx.GetContainerRange(0, MaxFetchedByRange)
require.NoError(err)
require.Len(containers, MaxFetchedByRange)
containers2, err := idx.GetContainerRange(1, MaxFetchedByRange)
require.NoError(err)
require.Len(containers2, MaxFetchedByRange)
require.Equal(containers[1], containers2[0])
require.Equal(containers[MaxFetchedByRange-1], containers2[MaxFetchedByRange-2])
// Should have last 2 elements
containers, err = idx.GetContainerRange(MaxFetchedByRange-1, MaxFetchedByRange)
require.NoError(err)
require.Len(containers, 2)
require.Equal(containers[1], containers2[MaxFetchedByRange-1])
require.Equal(containers[0], containers2[MaxFetchedByRange-2])
}
func TestDontIndexSameContainerTwice(t *testing.T) {
// Setup
require := require.New(t)
db := memdb.New()
// Use a test chain ID
testChainID := ids.GenerateTestID()
rt := testRuntime(testChainID)
idx, err := newIndex(db, log.NoLog{}, &mockable.Clock{})
require.NoError(err)
// Accept the same container twice
containerID := ids.GenerateTestID()
require.NoError(idx.Accept(rt, containerID, []byte{1, 2, 3}))
require.NoError(idx.Accept(rt, containerID, []byte{4, 5, 6}))
_, err = idx.GetContainerByIndex(1)
require.ErrorIs(err, errNoContainerAtIndex)
gotContainer, err := idx.GetContainerByID(containerID)
require.NoError(err)
require.Equal([]byte{1, 2, 3}, gotContainer.Bytes)
}