Files
zeekayandHanzo Dev 10a084c0b2 refactor(dex): fold pkg/lx into pkg/dex — one matcher, one package
The matching engine (pkg/lx, 45.5K LOC incl. tests) and the deterministic
core layered on it (pkg/dex) are one matcher spread across two packages
(dex imported lx in 12 files; lx imported neither). Fold lx into dex and
drop the "lx" name entirely — pkg/dex is now the single matcher package.

Pure rename/fold, ZERO logic change. Behavior proven identical: the merged
pkg/dex runs 457 top-level tests (431 former-lx + 26 former-dex) and 489
test funcs (468 + 21), all green — matching, batch (BatchMatchEqualsSequential,
run-to-run determinism, tile boundary), GPU/CPU parity, truncation, and CL
swap math all pass unchanged.

What moved:
- git mv all 101 pkg/lx/*.go + 1 .c into pkg/dex/ (package lx -> package dex).
- lx's swap_test.go -> swap_math_test.go (only filename collision with dex's
  existing swap_test.go).
- Rewrote imports repo-wide: 54 pkg/lx import lines removed; 42 external
  importers (api, client, consensus, dchain, dpdk, lxgpu, marketdata, test/,
  tests/) repointed to pkg/dex with lx.X -> dex.X; the 12 in-package dex files
  had lx.X -> bare X. 717 selector lines rewritten. Stale pkg/lx comment refs
  updated (pkg/lxgpu left intact).

Collisions resolved (2, both package-level vars):
- ErrNoLiquidity: lx's pool-level error (dexError, used only in swap.go, never
  referenced via qualifier) renamed ErrPoolNoLiquidity to match the existing
  ErrPool* convention; dex's router-level ErrNoLiquidity (public, has errors.Is
  tests) kept.
- priceMultiplierBig: identical after fold (both big.NewInt(PriceMultiplier));
  deduped by deleting dex's copy.

Not folded — pkg/orderbook: it is NOT the GPU seam (that is orderbook_gpu.go,
which lives in the engine and folded in here). pkg/orderbook is a zero-importer,
placeholder-cgo island whose 13 core domain identifiers (Order, OrderBook, Trade,
OrderType, OrderStatus, PriceLevel, Buy, Sell, Market, Limit, Filled,
PartiallyFilled, NewOrderBook) collide incompatibly with the engine's. Folding
it verbatim breaks the build; folding via rename reintroduces the exact parallel
duplication this fold removes. Left for owner decision (recommend deletion as
dead code) — see refactor notes.

Follow-on (separate repos, not touched): 19 files under luxfi/dex import
pkg/lx externally — lux/precompile/dex, lux/precompile-dex/dex,
lux/consensus/examples/01-simple-bridge, lux/_consensus-v12537/examples,
lux/cex/pkg/engine — repoint to pkg/dex after this lands.

Verified: CGO_ENABLED=0 GOWORK=off go build ./... clean; go vet ./... clean;
go test ./... -count=1 all green (22 ok / 0 fail).

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-02 00:57:08 -07:00

952 lines
22 KiB
Go

package consensus
import (
"testing"
"time"
"github.com/luxfi/dex/pkg/dex"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestIDString(t *testing.T) {
id := GenerateTestID("test")
str := id.String()
assert.NotEmpty(t, str)
assert.Len(t, str, 16) // 8 bytes in hex = 16 chars
}
func TestGenerateTestID(t *testing.T) {
// Without args
id1 := GenerateTestID()
id2 := GenerateTestID()
assert.NotEqual(t, id1, id2) // Should be unique
// With string arg
id3 := GenerateTestID("specific_string")
id4 := GenerateTestID("specific_string")
assert.Equal(t, id3, id4) // Same input = same output
}
func TestNewSecretKey(t *testing.T) {
sk, err := NewSecretKey()
require.NoError(t, err)
assert.NotNil(t, sk)
assert.Len(t, sk.Data, 32)
}
func TestSecretKeySign(t *testing.T) {
sk, err := NewSecretKey()
require.NoError(t, err)
data := []byte("test message")
sig := sk.Sign(data)
assert.NotNil(t, sig)
assert.Equal(t, data, sig.Data)
}
func TestNewCorona(t *testing.T) {
rt := NewCorona()
assert.NotNil(t, rt)
}
func TestCoronaInitialize(t *testing.T) {
rt := NewCorona()
tests := []struct {
name string
level SecurityLevel
}{
{"Low", SecurityLow},
{"Medium", SecurityMedium},
{"High", SecurityHigh},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := rt.Initialize(tt.level)
assert.NoError(t, err)
assert.Equal(t, int(tt.level), rt.level)
})
}
}
func TestCoronaGenerateKeyPair(t *testing.T) {
rt := NewCorona()
err := rt.Initialize(SecurityHigh)
require.NoError(t, err)
sk, pk, err := rt.GenerateKeyPair()
require.NoError(t, err)
assert.Len(t, sk, 32)
assert.Len(t, pk, 32)
}
func TestCoronaSignAndVerify(t *testing.T) {
rt := NewCorona()
err := rt.Initialize(SecurityHigh)
require.NoError(t, err)
sk, pk, err := rt.GenerateKeyPair()
require.NoError(t, err)
msg := []byte("test message")
sig, err := rt.Sign(msg, sk)
require.NoError(t, err)
assert.Len(t, sig, 64)
// Valid verification
valid := rt.Verify(msg, sig, pk)
assert.True(t, valid)
// Invalid message should fail
valid = rt.Verify([]byte("Wrong message"), sig, pk)
assert.False(t, valid)
// Invalid signature length should fail
valid = rt.Verify(msg, []byte("short"), pk)
assert.False(t, valid)
}
func TestSecurityLevels(t *testing.T) {
assert.Equal(t, SecurityLevel(128), SecurityLow)
assert.Equal(t, SecurityLevel(192), SecurityMedium)
assert.Equal(t, SecurityLevel(256), SecurityHigh)
}
func TestNewQuasar(t *testing.T) {
config := QuasarConfig{
Threshold: 3,
CertThreshold: 5,
SkipThreshold: 2,
SignatureScheme: "corona",
}
q, err := NewQuasar(config)
require.NoError(t, err)
assert.NotNil(t, q)
assert.Equal(t, 5, q.certThreshold)
assert.Equal(t, 2, q.skipThreshold)
}
func TestQuasarTrack(t *testing.T) {
config := QuasarConfig{CertThreshold: 5, SkipThreshold: 2}
q, err := NewQuasar(config)
require.NoError(t, err)
id := GenerateTestID("vertex1")
err = q.Track(id)
assert.NoError(t, err)
// Check it's tracked
q.mu.RLock()
tracked := q.tracked[id]
q.mu.RUnlock()
assert.True(t, tracked)
}
func TestQuasarTrackNil(t *testing.T) {
var q *Quasar
err := q.Track(GenerateTestID())
assert.NoError(t, err) // Should handle nil gracefully
}
func TestQuasarGenerateCertificate(t *testing.T) {
config := QuasarConfig{CertThreshold: 5, SkipThreshold: 2}
q, err := NewQuasar(config)
require.NoError(t, err)
id := GenerateTestID("test_cert")
// Track the ID first (required before generating certificate)
err = q.Track(id)
require.NoError(t, err)
cert, ok := q.GenerateCertificate(id)
// Should return a certificate after tracking
assert.NotNil(t, cert)
assert.True(t, ok)
assert.Equal(t, id, cert.VertexID)
assert.Equal(t, 5, cert.Threshold)
}
func TestPrecompute(t *testing.T) {
result, err := Precompute(nil)
require.NoError(t, err)
assert.NotNil(t, result)
// Result should be 32 bytes
bytes, ok := result.([]byte)
assert.True(t, ok)
assert.Len(t, bytes, 32)
}
func TestSignature(t *testing.T) {
sig := &Signature{Data: []byte("signature_data")}
assert.Equal(t, []byte("signature_data"), sig.Data)
}
func TestQuasarConcurrency(t *testing.T) {
config := QuasarConfig{CertThreshold: 5, SkipThreshold: 2}
q, err := NewQuasar(config)
require.NoError(t, err)
done := make(chan bool, 100)
// Concurrent tracking
for i := 0; i < 100; i++ {
go func(idx int) {
id := GenerateTestID()
_ = q.Track(id)
done <- true
}(i)
}
// Wait for all
for i := 0; i < 100; i++ {
<-done
}
// Should have 100 tracked items
q.mu.RLock()
count := len(q.tracked)
q.mu.RUnlock()
assert.Equal(t, 100, count)
}
func BenchmarkGenerateTestID(b *testing.B) {
for i := 0; i < b.N; i++ {
GenerateTestID()
}
}
func BenchmarkCoronaSign(b *testing.B) {
rt := NewCorona()
_ = rt.Initialize(SecurityHigh)
sk, _, _ := rt.GenerateKeyPair()
msg := []byte("benchmark message")
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, _ = rt.Sign(msg, sk)
}
}
func BenchmarkCoronaVerify(b *testing.B) {
rt := NewCorona()
_ = rt.Initialize(SecurityHigh)
sk, pk, _ := rt.GenerateKeyPair()
msg := []byte("benchmark message")
sig, _ := rt.Sign(msg, sk)
b.ResetTimer()
for i := 0; i < b.N; i++ {
rt.Verify(msg, sig, pk)
}
}
// === Quasar Extended Tests ===
func TestQuasarHasCertificate(t *testing.T) {
config := QuasarConfig{CertThreshold: 5, SkipThreshold: 2}
q, err := NewQuasar(config)
require.NoError(t, err)
id := GenerateTestID("cert_test")
// Should not have certificate before tracking
assert.False(t, q.HasCertificate(id))
// Track and generate certificate
err = q.Track(id)
require.NoError(t, err)
_, ok := q.GenerateCertificate(id)
require.True(t, ok)
// Should have certificate now
assert.True(t, q.HasCertificate(id))
}
func TestQuasarHasCertificateNil(t *testing.T) {
var q *Quasar
assert.False(t, q.HasCertificate(GenerateTestID()))
}
func TestQuasarHasSkipCertificate(t *testing.T) {
config := QuasarConfig{CertThreshold: 5, SkipThreshold: 2}
q, err := NewQuasar(config)
require.NoError(t, err)
id := GenerateTestID("skip_cert")
assert.False(t, q.HasSkipCertificate(id))
}
func TestQuasarHasSkipCertificateNil(t *testing.T) {
var q *Quasar
assert.False(t, q.HasSkipCertificate(GenerateTestID()))
}
func TestQuasarGetCertificate(t *testing.T) {
config := QuasarConfig{CertThreshold: 5, SkipThreshold: 2}
q, err := NewQuasar(config)
require.NoError(t, err)
id := GenerateTestID("get_cert")
// Not found before tracking
cert, ok := q.GetCertificate(id)
assert.Nil(t, cert)
assert.False(t, ok)
// Track and generate
err = q.Track(id)
require.NoError(t, err)
_, ok = q.GenerateCertificate(id)
require.True(t, ok)
// Should be found now
cert, ok = q.GetCertificate(id)
assert.NotNil(t, cert)
assert.True(t, ok)
assert.Equal(t, id, cert.VertexID)
}
func TestQuasarGetCertificateNil(t *testing.T) {
var q *Quasar
cert, ok := q.GetCertificate(GenerateTestID())
assert.Nil(t, cert)
assert.False(t, ok)
}
func TestQuasarCertThreshold(t *testing.T) {
config := QuasarConfig{CertThreshold: 10, SkipThreshold: 3}
q, err := NewQuasar(config)
require.NoError(t, err)
assert.Equal(t, 10, q.CertThreshold())
}
func TestQuasarSkipThreshold(t *testing.T) {
config := QuasarConfig{CertThreshold: 10, SkipThreshold: 3}
q, err := NewQuasar(config)
require.NoError(t, err)
assert.Equal(t, 3, q.SkipThreshold())
}
func TestQuasarHealthCheck(t *testing.T) {
config := QuasarConfig{CertThreshold: 5, SkipThreshold: 2}
q, err := NewQuasar(config)
require.NoError(t, err)
err = q.HealthCheck()
assert.NoError(t, err)
}
func TestQuasarHealthCheckNil(t *testing.T) {
var q *Quasar
err := q.HealthCheck()
assert.Error(t, err)
}
func TestQuasarInitialize(t *testing.T) {
config := QuasarConfig{CertThreshold: 5, SkipThreshold: 2}
q, err := NewQuasar(config)
require.NoError(t, err)
genesis := GenerateTestID("genesis")
err = q.Initialize(genesis)
assert.NoError(t, err)
// Genesis should have a certificate
assert.True(t, q.HasCertificate(genesis))
}
func TestQuasarInitializeNil(t *testing.T) {
var q *Quasar
err := q.Initialize(GenerateTestID())
assert.Error(t, err)
}
func TestQuasarCertificateCount(t *testing.T) {
config := QuasarConfig{CertThreshold: 5, SkipThreshold: 2}
q, err := NewQuasar(config)
require.NoError(t, err)
assert.Equal(t, 0, q.CertificateCount())
// Track and generate
id := GenerateTestID("count_test")
err = q.Track(id)
require.NoError(t, err)
_, _ = q.GenerateCertificate(id)
assert.Equal(t, 1, q.CertificateCount())
}
func TestQuasarCertificateCountNil(t *testing.T) {
var q *Quasar
assert.Equal(t, 0, q.CertificateCount())
}
func TestQuasarSkipCertificateCount(t *testing.T) {
config := QuasarConfig{CertThreshold: 5, SkipThreshold: 2}
q, err := NewQuasar(config)
require.NoError(t, err)
assert.Equal(t, 0, q.SkipCertificateCount())
}
func TestQuasarSkipCertificateCountNil(t *testing.T) {
var q *Quasar
assert.Equal(t, 0, q.SkipCertificateCount())
}
func TestQuasarGenerateCertificateNotTracked(t *testing.T) {
config := QuasarConfig{CertThreshold: 5, SkipThreshold: 2}
q, err := NewQuasar(config)
require.NoError(t, err)
id := GenerateTestID("untracked")
// Should fail for untracked ID
cert, ok := q.GenerateCertificate(id)
assert.Nil(t, cert)
assert.False(t, ok)
}
func TestQuasarGenerateCertificateNil(t *testing.T) {
var q *Quasar
cert, ok := q.GenerateCertificate(GenerateTestID())
assert.Nil(t, cert)
assert.False(t, ok)
}
func TestQuasarGenerateCertificateWithProof(t *testing.T) {
config := QuasarConfig{CertThreshold: 3, SkipThreshold: 2}
q, err := NewQuasar(config)
require.NoError(t, err)
// Generate multiple certificates
for i := 0; i < 5; i++ {
id := GenerateTestID()
_ = q.Track(id)
_, _ = q.GenerateCertificate(id)
}
// New certificate should have proofs from previous ones
id := GenerateTestID()
_ = q.Track(id)
cert, ok := q.GenerateCertificate(id)
assert.True(t, ok)
assert.LessOrEqual(t, len(cert.Proof), 3) // Max 3 proofs
}
// === DAGOrderBook Tests ===
func TestNewDAGOrderBook(t *testing.T) {
dob, err := NewDAGOrderBook("node1", "BTC/USDC")
require.NoError(t, err)
assert.NotNil(t, dob)
assert.Equal(t, "node1", dob.nodeID)
assert.Equal(t, "BTC/USDC", dob.symbol)
assert.NotNil(t, dob.vertices)
assert.NotNil(t, dob.quasar)
}
func TestNewLuxDAGOrderBook(t *testing.T) {
lux, err := NewLuxDAGOrderBook("node1", "ETH/USDC")
require.NoError(t, err)
assert.NotNil(t, lux)
assert.NotNil(t, lux.blsKey)
assert.NotNil(t, lux.corona)
assert.NotNil(t, lux.quasar)
assert.NotNil(t, lux.votes)
assert.NotNil(t, lux.certificates)
}
func TestDAGOrderBookAddOrder(t *testing.T) {
dob, err := NewDAGOrderBook("node1", "BTC/USDC")
require.NoError(t, err)
order := &dex.Order{
ID: 1,
Side: dex.Buy,
Type: dex.Limit,
Price: 50000.0,
Size: 1.0,
}
vertex, err := dob.AddOrder(order)
require.NoError(t, err)
assert.NotNil(t, vertex)
assert.Equal(t, order, vertex.Order)
assert.Equal(t, uint64(1), vertex.Height)
assert.Equal(t, "node1", vertex.NodeID)
}
func TestDAGOrderBookAddMultipleOrders(t *testing.T) {
dob, err := NewDAGOrderBook("node1", "BTC/USDC")
require.NoError(t, err)
for i := 1; i <= 5; i++ {
order := &dex.Order{
ID: uint64(i),
Side: dex.Buy,
Type: dex.Limit,
Price: 50000.0 + float64(i*100),
Size: 1.0,
}
vertex, err := dob.AddOrder(order)
require.NoError(t, err)
assert.Equal(t, uint64(i), vertex.Height)
}
stats := dob.GetStats()
assert.Equal(t, 5, stats["vertices"])
// Note: LuxDAGOrderBook.GetStats() doesn't return height
assert.NotNil(t, stats["finalized"])
}
func TestDAGOrderBookGetStats(t *testing.T) {
dob, err := NewDAGOrderBook("node1", "BTC/USDC")
require.NoError(t, err)
stats := dob.GetStats()
assert.Equal(t, "node1", stats["node_id"])
assert.Equal(t, 0, stats["vertices"])
assert.Equal(t, 0, stats["finalized"])
assert.Equal(t, 0, stats["frontier_size"])
// Note: LuxDAGOrderBook.GetStats() uses different fields than base DAGOrderBook
assert.NotNil(t, stats["fpc_enabled"])
}
func TestLuxDAGOrderBookAddOrder(t *testing.T) {
lux, err := NewLuxDAGOrderBook("node1", "BTC/USDC")
require.NoError(t, err)
order := &dex.Order{
ID: 1,
Side: dex.Buy,
Type: dex.Limit,
Price: 50000.0,
Size: 1.0,
}
vertex, err := lux.AddOrder(order)
require.NoError(t, err)
assert.NotNil(t, vertex)
// Check vote state was initialized
lux.mu.RLock()
voteState, exists := lux.votes[vertex.ID]
lux.mu.RUnlock()
assert.True(t, exists)
assert.Equal(t, 1, voteState.Votes)
assert.Equal(t, 1.0, voteState.Confidence)
}
func TestLuxDAGOrderBookGetStats(t *testing.T) {
lux, err := NewLuxDAGOrderBook("node1", "BTC/USDC")
require.NoError(t, err)
stats := lux.GetStats()
assert.Equal(t, "node1", stats["node_id"])
assert.Equal(t, 0, stats["vertices"])
assert.Equal(t, 0, stats["finalized"])
assert.Equal(t, true, stats["fpc_enabled"])
assert.NotNil(t, stats["vote_threshold"])
}
func TestLuxDAGOrderBookRunFPCRound(t *testing.T) {
lux, err := NewLuxDAGOrderBook("node1", "BTC/USDC")
require.NoError(t, err)
// Add an order
order := &dex.Order{
ID: 1,
Side: dex.Buy,
Type: dex.Limit,
Price: 50000.0,
Size: 1.0,
}
_, err = lux.AddOrder(order)
require.NoError(t, err)
// Run FPC round
err = lux.runFPCRound(1)
assert.NoError(t, err)
// Threshold should update
assert.GreaterOrEqual(t, lux.voteThreshold, lux.luxConfig.ThetaMin)
}
func TestLuxDAGOrderBookProcessRemoteVertex(t *testing.T) {
lux, err := NewLuxDAGOrderBook("node1", "BTC/USDC")
require.NoError(t, err)
vertex := &OrderVertex{
ID: GenerateTestID("remote_vertex"),
Order: &dex.Order{ID: 1, Side: dex.Sell, Type: dex.Limit, Price: 50000.0, Size: 1.0},
NodeID: "node2",
Height: 1,
Timestamp: time.Now(),
}
cert := &QuantumCertificate{
VertexID: vertex.ID,
BLSSignature: &Signature{Data: []byte("test")},
CoronaCert: []byte("cert"),
Height: 1,
VoteThreshold: 0.55,
}
err = lux.ProcessRemoteVertex(vertex, cert)
assert.NoError(t, err)
// Verify vertex was added
lux.mu.RLock()
_, exists := lux.vertices[vertex.ID]
lux.mu.RUnlock()
assert.True(t, exists)
}
func TestLuxDAGOrderBookProcessRemoteVertexNilCert(t *testing.T) {
lux, err := NewLuxDAGOrderBook("node1", "BTC/USDC")
require.NoError(t, err)
vertex := &OrderVertex{
ID: GenerateTestID("remote"),
Order: &dex.Order{ID: 1, Side: dex.Sell, Type: dex.Limit, Price: 50000.0, Size: 1.0},
NodeID: "node2",
Height: 1,
}
err = lux.ProcessRemoteVertex(vertex, nil)
assert.Error(t, err)
}
func TestLuxDAGOrderBookProcessRemoteVertexMismatchID(t *testing.T) {
lux, err := NewLuxDAGOrderBook("node1", "BTC/USDC")
require.NoError(t, err)
vertex := &OrderVertex{
ID: GenerateTestID("v1"),
Order: &dex.Order{ID: 1, Side: dex.Sell, Type: dex.Limit, Price: 50000.0, Size: 1.0},
NodeID: "node2",
Height: 1,
}
cert := &QuantumCertificate{
VertexID: GenerateTestID("v2"), // Different ID
VoteThreshold: 0.55,
}
err = lux.ProcessRemoteVertex(vertex, cert)
assert.Error(t, err)
}
func TestLuxDAGOrderBookProcessRemoteVertexLowThreshold(t *testing.T) {
lux, err := NewLuxDAGOrderBook("node1", "BTC/USDC")
require.NoError(t, err)
vertex := &OrderVertex{
ID: GenerateTestID("low_thresh"),
Order: &dex.Order{ID: 1, Side: dex.Sell, Type: dex.Limit, Price: 50000.0, Size: 1.0},
NodeID: "node2",
Height: 1,
}
cert := &QuantumCertificate{
VertexID: vertex.ID,
VoteThreshold: 0.01, // Too low
}
err = lux.ProcessRemoteVertex(vertex, cert)
assert.Error(t, err)
}
func TestLuxDAGOrderBookGenerateQuantumCertificate(t *testing.T) {
lux, err := NewLuxDAGOrderBook("node1", "BTC/USDC")
require.NoError(t, err)
order := &dex.Order{
ID: 1,
Side: dex.Buy,
Type: dex.Limit,
Price: 50000.0,
Size: 1.0,
}
vertex, err := lux.AddOrder(order)
require.NoError(t, err)
cert, ok := lux.generateQuantumCertificate(vertex.ID, vertex)
assert.True(t, ok)
assert.NotNil(t, cert)
assert.Equal(t, vertex.ID, cert.VertexID)
assert.Equal(t, vertex.Height, cert.Height)
assert.NotNil(t, cert.BLSSignature)
}
func TestLuxDAGOrderBookValidateQuantumCertificate(t *testing.T) {
lux, err := NewLuxDAGOrderBook("node1", "BTC/USDC")
require.NoError(t, err)
vertex := &OrderVertex{
ID: GenerateTestID("validate_cert"),
Order: &dex.Order{ID: 1, Side: dex.Buy, Type: dex.Limit, Price: 50000.0, Size: 1.0},
NodeID: "node1",
Height: 1,
}
cert := &QuantumCertificate{
VertexID: vertex.ID,
VoteThreshold: 0.60,
}
err = lux.validateQuantumCertificate(vertex, cert)
assert.NoError(t, err)
}
func TestLuxDAGOrderBookProcessQuasarCertificates(t *testing.T) {
lux, err := NewLuxDAGOrderBook("node1", "BTC/USDC")
require.NoError(t, err)
// Add an order which tracks in quasar
order := &dex.Order{
ID: 1,
Side: dex.Buy,
Type: dex.Limit,
Price: 50000.0,
Size: 1.0,
}
vertex, err := lux.AddOrder(order)
require.NoError(t, err)
// Process quasar certificates
lux.processQuasarCertificates()
// Vertex should be finalized
lux.mu.RLock()
finalized := lux.finalized[vertex.ID]
lux.mu.RUnlock()
assert.True(t, finalized)
}
func TestLuxDAGOrderBookCheckQuantumFinality(t *testing.T) {
lux, err := NewLuxDAGOrderBook("node1", "BTC/USDC")
require.NoError(t, err)
// Add certificate directly
id := GenerateTestID("quantum_finality")
lux.mu.Lock()
lux.certificates[id] = &QuantumCertificate{VertexID: id}
lux.mu.Unlock()
// Check quantum finality
lux.checkQuantumFinality()
// Should be finalized now
lux.mu.RLock()
finalized := lux.finalized[id]
lux.mu.RUnlock()
assert.True(t, finalized)
}
func TestLuxDAGOrderBookFinalizeVertex(t *testing.T) {
lux, err := NewLuxDAGOrderBook("node1", "BTC/USDC")
require.NoError(t, err)
id := GenerateTestID("finalize_test")
lux.mu.Lock()
lux.finalizeVertex(id)
lux.mu.Unlock()
lux.mu.RLock()
finalized := lux.finalized[id]
lux.mu.RUnlock()
assert.True(t, finalized)
assert.Equal(t, uint64(1), lux.finalityCount.Load())
}
func TestDAGOrderBookShutdown(t *testing.T) {
dob, err := NewDAGOrderBook("node1", "BTC/USDC")
require.NoError(t, err)
// Start consensus in background
go func() {
_ = dob.RunConsensus()
}()
// Allow some time for consensus to run
time.Sleep(50 * time.Millisecond)
// Shutdown should not block
dob.Shutdown()
}
func TestLuxDAGOrderBookShutdown(t *testing.T) {
lux, err := NewLuxDAGOrderBook("node1", "BTC/USDC")
require.NoError(t, err)
// Start consensus in background
go func() {
_ = lux.RunLuxConsensus()
}()
// Allow some time for consensus to run
time.Sleep(50 * time.Millisecond)
// Shutdown should not block
lux.Shutdown()
}
func TestLuxDAGOrderBookRunFPCConsensus(t *testing.T) {
lux, err := NewLuxDAGOrderBook("node1", "BTC/USDC")
require.NoError(t, err)
// Start FPC consensus in background
go func() {
_ = lux.RunFPCConsensus()
}()
// Allow some time for consensus to run
time.Sleep(100 * time.Millisecond)
// Shutdown
lux.Shutdown()
}
func TestLuxDAGOrderBookCreateCertificateMessage(t *testing.T) {
lux, err := NewLuxDAGOrderBook("node1", "BTC/USDC")
require.NoError(t, err)
vertex := &OrderVertex{
ID: GenerateTestID("cert_msg"),
Order: &dex.Order{ID: 1, Side: dex.Buy, Type: dex.Limit, Price: 50000.0, Size: 1.0},
NodeID: "node1",
Height: 1,
}
msg := lux.createCertificateMessage(vertex)
assert.NotNil(t, msg)
assert.Len(t, msg, 32) // SHA256 output
}
func TestOrderVertexFields(t *testing.T) {
vertex := &OrderVertex{
ID: GenerateTestID("test"),
Order: &dex.Order{ID: 1, Side: dex.Buy},
NodeID: "node1",
Height: 10,
Parents: []ID{GenerateTestID("parent1"), GenerateTestID("parent2")},
Timestamp: time.Now(),
Trades: []*dex.Trade{{ID: 1, Price: 50000.0}},
}
assert.Equal(t, "node1", vertex.NodeID)
assert.Equal(t, uint64(10), vertex.Height)
assert.Len(t, vertex.Parents, 2)
assert.Len(t, vertex.Trades, 1)
}
func TestVoteState(t *testing.T) {
vs := &VoteState{
Votes: 5,
Confidence: 0.75,
Round: 3,
}
assert.Equal(t, 5, vs.Votes)
assert.Equal(t, 0.75, vs.Confidence)
assert.Equal(t, 3, vs.Round)
}
func TestQuantumCertificateFields(t *testing.T) {
id := GenerateTestID("qc")
cert := &QuantumCertificate{
VertexID: id,
BLSSignature: &Signature{Data: []byte("sig")},
CoronaCert: []byte("corona"),
Timestamp: time.Now(),
Height: 5,
VoteThreshold: 0.67,
Threshold: 15,
Item: id,
Proof: []ID{GenerateTestID("proof1")},
}
assert.Equal(t, id, cert.VertexID)
assert.NotNil(t, cert.BLSSignature)
assert.NotNil(t, cert.CoronaCert)
assert.Equal(t, uint64(5), cert.Height)
assert.Equal(t, 0.67, cert.VoteThreshold)
assert.Equal(t, 15, cert.Threshold)
assert.Len(t, cert.Proof, 1)
}
func TestLuxConsensusConfig(t *testing.T) {
config := LuxConsensusConfig{
Enable: true,
ThetaMin: 0.55,
ThetaMax: 0.65,
VoteLimitPerBlock: 256,
VoteThreshold: 0.55,
RoundDuration: 50 * time.Millisecond,
TimeWindow: 30 * time.Second,
}
assert.True(t, config.Enable)
assert.Equal(t, 0.55, config.ThetaMin)
assert.Equal(t, 0.65, config.ThetaMax)
assert.Equal(t, 256, config.VoteLimitPerBlock)
}
// === Benchmarks ===
func BenchmarkDAGOrderBookAddOrder(b *testing.B) {
dob, _ := NewDAGOrderBook("node1", "BTC/USDC")
b.ResetTimer()
for i := 0; i < b.N; i++ {
order := &dex.Order{
ID: uint64(i),
Side: dex.Buy,
Type: dex.Limit,
Price: 50000.0,
Size: 1.0,
}
_, _ = dob.AddOrder(order)
}
}
func BenchmarkLuxDAGOrderBookAddOrder(b *testing.B) {
lux, _ := NewLuxDAGOrderBook("node1", "BTC/USDC")
b.ResetTimer()
for i := 0; i < b.N; i++ {
order := &dex.Order{
ID: uint64(i),
Side: dex.Buy,
Type: dex.Limit,
Price: 50000.0,
Size: 1.0,
}
_, _ = lux.AddOrder(order)
}
}
func BenchmarkQuasarTrackAndCertificate(b *testing.B) {
config := QuasarConfig{CertThreshold: 5, SkipThreshold: 2}
q, _ := NewQuasar(config)
b.ResetTimer()
for i := 0; i < b.N; i++ {
id := GenerateTestID()
_ = q.Track(id)
_, _ = q.GenerateCertificate(id)
}
}