Files
zeekayandHanzo Dev e808906131 the corporate name is Lux Industries Inc
Lux Partners Limited is not the entity behind this work. Every place the
old name stood — copyright lines, site footers, brand config, legal and
compliance text — now names the company that actually holds it.

lux.fund is the exception and is not renamed to match: that site belongs
to Lux Assets Management LLC, a different company, and it says so.

Two kinds of line were left for a person rather than rewritten. A dated
news item recording that Lux Partners Limited was established in the Isle
of Man is a historical fact, and renaming it would falsify the record. And
a sentence asserting that the company is domiciled in the Isle of Man is a
claim about a jurisdiction, not a name — an Inc or an LLC is not an Isle
of Man company, so swapping the name there would assert something untrue.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-28 12:58:35 -07:00

233 lines
6.6 KiB
Go

// Copyright (C) 2019-2025, Lux Industries Inc All rights reserved.
// See the file LICENSE for licensing terms.
package chain
import (
"context"
"testing"
"time"
"github.com/stretchr/testify/require"
"github.com/luxfi/ids"
)
// TestStatusOrProcessingAccepted verifies that blocks with Accepted status (status=2)
// are NOT in the processing set and ARE marked as preferred at their height.
func TestStatusOrProcessingAccepted(t *testing.T) {
require := require.New(t)
engine := NewTransitiveEngine()
ctx := context.Background()
params := TransitiveParams{
K: 1,
AlphaPreference: 1,
AlphaConfidence: 1,
Beta: 1,
}
genesisID := ids.GenerateTestID()
genesisHeight := uint64(0)
genesisTime := time.Now()
require.NoError(engine.Initialize(ctx, params, genesisID, genesisHeight, genesisTime))
// Genesis is already accepted
genesis := engine.blocks[genesisID]
require.Equal(StatusAccepted, genesis.Status())
// Accepted blocks should NOT be in processing set
require.False(engine.processing.Contains(genesisID))
// Genesis should be the preference (last accepted block)
require.Equal(genesisID, engine.preference)
// Add a child block and accept it
block1 := &TestBlock{
IDV: ids.GenerateTestID(),
HeightV: 1,
ParentV: genesisID,
TimestampV: genesisTime.Add(time.Second),
}
require.NoError(engine.Add(block1))
// Block 1 should be in processing initially
require.True(engine.processing.Contains(block1.ID()))
require.Equal(StatusProcessing, block1.Status())
// Vote to accept block1
votes := NewBag[ids.ID]()
votes.Add(block1.ID())
require.NoError(engine.RecordPoll(ctx, votes))
// Block 1 should now be accepted
require.Equal(StatusAccepted, block1.Status())
// Accepted block should NOT be in processing set
require.False(engine.processing.Contains(block1.ID()))
// Block 1 should be the new preference
require.Equal(block1.ID(), engine.preference)
require.Equal(block1.ID(), engine.lastAccepted)
}
// TestStatusOrProcessingRejected verifies that blocks with Rejected status (status=3)
// are NOT in the processing set and are NOT marked as preferred.
func TestStatusOrProcessingRejected(t *testing.T) {
require := require.New(t)
engine := NewTransitiveEngine()
ctx := context.Background()
params := TransitiveParams{
K: 1,
AlphaPreference: 1,
AlphaConfidence: 1,
Beta: 1,
}
genesisID := ids.GenerateTestID()
genesisHeight := uint64(0)
genesisTime := time.Now()
require.NoError(engine.Initialize(ctx, params, genesisID, genesisHeight, genesisTime))
// Build two competing blocks
block0 := &TestBlock{
IDV: ids.GenerateTestID(),
HeightV: 1,
ParentV: genesisID,
TimestampV: genesisTime.Add(time.Second),
}
block1 := &TestBlock{
IDV: ids.GenerateTestID(),
HeightV: 1,
ParentV: genesisID,
TimestampV: genesisTime.Add(time.Second),
}
require.NoError(engine.Add(block0))
require.NoError(engine.Add(block1))
// Both should be in processing initially
require.True(engine.processing.Contains(block0.ID()))
require.True(engine.processing.Contains(block1.ID()))
// Vote to accept block0 (which will reject block1)
votes := NewBag[ids.ID]()
votes.Add(block0.ID())
require.NoError(engine.RecordPoll(ctx, votes))
// Block 0 should be accepted, block 1 should be rejected
require.Equal(StatusAccepted, block0.Status())
require.Equal(StatusRejected, block1.Status())
// Rejected block should NOT be in processing set
require.False(engine.processing.Contains(block1.ID()))
// Rejected block should NOT be the preference
require.NotEqual(block1.ID(), engine.preference)
require.Equal(block0.ID(), engine.preference)
}
// TestStatusOrProcessingUnissued verifies that blocks that haven't been added
// to consensus (unissued) are NOT in the processing set and are NOT marked as preferred.
func TestStatusOrProcessingUnissued(t *testing.T) {
require := require.New(t)
engine := NewTransitiveEngine()
ctx := context.Background()
params := TransitiveParams{
K: 1,
AlphaPreference: 1,
AlphaConfidence: 1,
Beta: 1,
}
genesisID := ids.GenerateTestID()
genesisHeight := uint64(0)
genesisTime := time.Now()
require.NoError(engine.Initialize(ctx, params, genesisID, genesisHeight, genesisTime))
// Build a block but don't add it to the engine
unissuedBlock := &TestBlock{
IDV: ids.GenerateTestID(),
HeightV: 1,
ParentV: genesisID,
TimestampV: genesisTime.Add(time.Second),
}
// Unissued block should NOT be in processing set
require.False(engine.processing.Contains(unissuedBlock.ID()))
// Unissued block should NOT be the preference
require.NotEqual(unissuedBlock.ID(), engine.preference)
// Preference should still be genesis
require.Equal(genesisID, engine.preference)
// Number of processing blocks should be 0
require.Zero(engine.NumProcessing())
}
// TestStatusOrProcessingIssued verifies that blocks added via Add() ARE in the
// processing set and ARE marked as preferred (if they extend the preferred chain).
func TestStatusOrProcessingIssued(t *testing.T) {
require := require.New(t)
engine := NewTransitiveEngine()
ctx := context.Background()
params := TransitiveParams{
K: 1,
AlphaPreference: 1,
AlphaConfidence: 1,
Beta: 1,
}
genesisID := ids.GenerateTestID()
genesisHeight := uint64(0)
genesisTime := time.Now()
require.NoError(engine.Initialize(ctx, params, genesisID, genesisHeight, genesisTime))
// Build and add a block that extends genesis
block1 := &TestBlock{
IDV: ids.GenerateTestID(),
HeightV: 1,
ParentV: genesisID,
TimestampV: genesisTime.Add(time.Second),
}
require.NoError(engine.Add(block1))
// Issued block should be in processing set
require.True(engine.processing.Contains(block1.ID()))
// Status should be Processing
require.Equal(StatusProcessing, block1.Status())
// Since block1 extends the current preference (genesis), it should become the new preference
require.Equal(block1.ID(), engine.preference)
// Number of processing blocks should be 1
require.Equal(1, engine.NumProcessing())
// Add another block extending block1
block2 := &TestBlock{
IDV: ids.GenerateTestID(),
HeightV: 2,
ParentV: block1.ID(),
TimestampV: genesisTime.Add(2 * time.Second),
}
require.NoError(engine.Add(block2))
// Block2 should also be in processing
require.True(engine.processing.Contains(block2.ID()))
// Block2 should be the new preference (extends current preference)
require.Equal(block2.ID(), engine.preference)
// Number of processing blocks should be 2
require.Equal(2, engine.NumProcessing())
}