Files
zeekayandHanzo Dev da299df77d 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 13:05:15 -07:00

501 lines
11 KiB
Go

// Copyright (C) 2020-2025, Lux Industries Inc All rights reserved.
// See the file LICENSE for licensing terms.
package blockchain
import (
"context"
"encoding/json"
"math/big"
"testing"
"github.com/luxfi/geth/common"
log "github.com/luxfi/log"
"github.com/luxfi/sdk/network"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestBuilder_CreateBlockchain(t *testing.T) {
logger := log.NewNoOpLogger()
builder := NewBuilder(logger)
tests := []struct {
name string
params *CreateParams
wantErr bool
}{
{
name: "create EVM L1",
params: &CreateParams{
Name: "test-evm-l1",
Type: TypeL1,
VMType: VMTypeEVM,
ChainID: big.NewInt(12345),
Allocations: map[common.Address]GenesisAccount{
common.HexToAddress("0x123"): {
Balance: big.NewInt(1000000),
},
},
},
wantErr: false,
},
{
name: "create WASM L2",
params: &CreateParams{
Name: "test-wasm-l2",
Type: TypeL2,
VMType: VMTypeWASM,
ChainID: big.NewInt(23456),
L2Config: &L2Config{
SequencerType: "centralized",
DALayer: "celestia",
SettlementChain: "chain-123",
},
},
wantErr: false,
},
{
name: "create TokenVM L3",
params: &CreateParams{
Name: "test-token-l3",
Type: TypeL3,
VMType: VMTypeTokenVM,
ChainID: big.NewInt(34567),
InitialSupply: big.NewInt(1000000000),
L3Config: &L3Config{
L2Chain: "l2-chain-456",
AppType: "defi",
AppConfig: map[string]interface{}{
"dex": true,
"lending": true,
},
},
},
wantErr: false,
},
{
name: "with custom genesis",
params: &CreateParams{
Name: "test-custom-genesis",
Type: TypeL1,
VMType: VMTypeEVM,
Genesis: []byte(`{"chainId": 99999}`),
},
wantErr: false,
},
{
name: "with custom chain config",
params: &CreateParams{
Name: "test-custom-config",
Type: TypeL1,
VMType: VMTypeEVM,
ChainConfig: []byte(`{
"chainId": 88888,
"consensus": {
"type": "lux",
"parameters": {
"k": 15
}
}
}`),
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ctx := context.Background()
blockchain, err := builder.CreateBlockchain(ctx, tt.params)
if tt.wantErr {
assert.Error(t, err)
assert.Nil(t, blockchain)
} else {
assert.NoError(t, err)
assert.NotNil(t, blockchain)
assert.Equal(t, tt.params.Name, blockchain.Name)
assert.Equal(t, tt.params.Type, blockchain.Type)
assert.Equal(t, tt.params.VMType, blockchain.VMType)
assert.Equal(t, StatusCreated, blockchain.Status)
assert.NotEmpty(t, blockchain.ID)
assert.NotNil(t, blockchain.Genesis)
assert.NotNil(t, blockchain.ChainConfig)
// Verify blockchain is stored
stored, err := builder.GetBlockchain(blockchain.ID)
assert.NoError(t, err)
assert.Equal(t, blockchain, stored)
}
})
}
}
func TestBuilder_Deploy(t *testing.T) {
logger := log.NewNoOpLogger()
builder := NewBuilder(logger)
ctx := context.Background()
// Create a test blockchain
blockchain, err := builder.CreateBlockchain(ctx, &CreateParams{
Name: "deploy-test",
Type: TypeL1,
VMType: VMTypeEVM,
ChainID: big.NewInt(55555),
})
require.NoError(t, err)
// Create a test network
testNetwork := &network.Network{
ID: "test-network",
Name: "Test Network",
Type: network.NetworkTypeLocal,
Status: network.NetworkStatusRunning,
}
t.Run("deploy L1", func(t *testing.T) {
err := builder.Deploy(ctx, blockchain, testNetwork)
// Since actual deployment is not implemented, we expect no error
// but the blockchain should be marked as deployed
assert.NoError(t, err)
assert.Equal(t, StatusDeployed, blockchain.Status)
assert.NotNil(t, blockchain.DeployedAt)
assert.Equal(t, testNetwork.ID, blockchain.NetworkID)
})
t.Run("deploy L2", func(t *testing.T) {
l2Blockchain, err := builder.CreateBlockchain(ctx, &CreateParams{
Name: "l2-deploy-test",
Type: TypeL2,
VMType: VMTypeEVM,
L2Config: &L2Config{
SequencerType: "centralized",
},
})
require.NoError(t, err)
err = builder.Deploy(ctx, l2Blockchain, testNetwork)
assert.NoError(t, err)
assert.Equal(t, StatusDeployed, l2Blockchain.Status)
})
t.Run("deploy L3", func(t *testing.T) {
l3Blockchain, err := builder.CreateBlockchain(ctx, &CreateParams{
Name: "l3-deploy-test",
Type: TypeL3,
VMType: VMTypeWASM,
L3Config: &L3Config{
L2Chain: "l2-chain",
AppType: "gaming",
},
})
require.NoError(t, err)
err = builder.Deploy(ctx, l3Blockchain, testNetwork)
assert.NoError(t, err)
assert.Equal(t, StatusDeployed, l3Blockchain.Status)
})
t.Run("deploy error recovery", func(t *testing.T) {
errorBlockchain, err := builder.CreateBlockchain(ctx, &CreateParams{
Name: "error-test",
Type: BlockchainType("invalid"),
VMType: VMTypeEVM,
})
require.NoError(t, err)
err = builder.Deploy(ctx, errorBlockchain, testNetwork)
assert.Error(t, err)
assert.Equal(t, StatusError, errorBlockchain.Status)
})
}
func TestBuilder_GenerateGenesis(t *testing.T) {
logger := log.NewNoOpLogger()
builder := NewBuilder(logger)
tests := []struct {
name string
params *GenesisParams
wantErr bool
check func(t *testing.T, genesis []byte)
}{
{
name: "EVM genesis",
params: &GenesisParams{
VMType: VMTypeEVM,
ChainID: big.NewInt(12345),
Allocations: map[common.Address]GenesisAccount{
common.HexToAddress("0xabc"): {
Balance: big.NewInt(1000000),
},
},
},
wantErr: false,
check: func(t *testing.T, genesis []byte) {
var g map[string]interface{}
err := json.Unmarshal(genesis, &g)
assert.NoError(t, err)
config, ok := g["config"].(map[string]interface{})
assert.True(t, ok)
chainID, ok := config["chainId"].(float64)
assert.True(t, ok)
assert.Equal(t, float64(12345), chainID)
},
},
{
name: "WASM genesis",
params: &GenesisParams{
VMType: VMTypeWASM,
ChainID: big.NewInt(23456),
},
wantErr: false,
check: func(t *testing.T, genesis []byte) {
var g map[string]interface{}
err := json.Unmarshal(genesis, &g)
assert.NoError(t, err)
assert.Equal(t, "wasm", g["vmType"])
},
},
{
name: "TokenVM genesis",
params: &GenesisParams{
VMType: VMTypeTokenVM,
ChainID: big.NewInt(34567),
InitialSupply: big.NewInt(1000000000),
},
wantErr: false,
check: func(t *testing.T, genesis []byte) {
var g map[string]interface{}
err := json.Unmarshal(genesis, &g)
assert.NoError(t, err)
assert.Equal(t, "tokenvm", g["vmType"])
assert.NotNil(t, g["supply"])
},
},
{
name: "unsupported VM type",
params: &GenesisParams{
VMType: VMType("unsupported"),
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
genesis, err := builder.GenerateGenesis(tt.params)
if tt.wantErr {
assert.Error(t, err)
assert.Nil(t, genesis)
} else {
assert.NoError(t, err)
assert.NotNil(t, genesis)
if tt.check != nil {
tt.check(t, genesis)
}
}
})
}
}
func TestBuilder_ValidateConfig(t *testing.T) {
logger := log.NewNoOpLogger()
builder := NewBuilder(logger)
tests := []struct {
name string
config []byte
wantErr bool
errMsg string
}{
{
name: "valid config",
config: []byte(`{
"chainId": 12345,
"consensus": {
"type": "lux"
},
"vm": {
"type": "evm"
}
}`),
wantErr: false,
},
{
name: "missing required field - chainId",
config: []byte(`{
"consensus": {
"type": "lux"
},
"vm": {
"type": "evm"
}
}`),
wantErr: true,
errMsg: "missing required field: chainId",
},
{
name: "missing required field - consensus",
config: []byte(`{
"chainId": 12345,
"vm": {
"type": "evm"
}
}`),
wantErr: true,
errMsg: "missing required field: consensus",
},
{
name: "missing required field - vm",
config: []byte(`{
"chainId": 12345,
"consensus": {
"type": "lux"
}
}`),
wantErr: true,
errMsg: "missing required field: vm",
},
{
name: "invalid JSON",
config: []byte(`{invalid json`),
wantErr: true,
errMsg: "invalid configuration format",
},
{
name: "empty config",
config: []byte(`{}`),
wantErr: true,
errMsg: "missing required field",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := builder.ValidateConfig(tt.config)
if tt.wantErr {
assert.Error(t, err)
assert.Contains(t, err.Error(), tt.errMsg)
} else {
assert.NoError(t, err)
}
})
}
}
func TestBuilder_ListBlockchains(t *testing.T) {
logger := log.NewNoOpLogger()
builder := NewBuilder(logger)
ctx := context.Background()
// Create multiple blockchains
blockchains := []struct {
name string
bcType BlockchainType
vmType VMType
}{
{"chain-1", TypeL1, VMTypeEVM},
{"chain-2", TypeL2, VMTypeWASM},
{"chain-3", TypeL3, VMTypeTokenVM},
}
createdIDs := make(map[string]bool)
for _, bc := range blockchains {
blockchain, err := builder.CreateBlockchain(ctx, &CreateParams{
Name: bc.name,
Type: bc.bcType,
VMType: bc.vmType,
})
require.NoError(t, err)
createdIDs[blockchain.ID] = true
}
// List all blockchains
list := builder.ListBlockchains()
assert.Len(t, list, 3)
// Verify all blockchains are present
for _, bc := range list {
assert.True(t, createdIDs[bc.ID])
}
}
func TestBuilder_GetBlockchain(t *testing.T) {
logger := log.NewNoOpLogger()
builder := NewBuilder(logger)
ctx := context.Background()
// Create a test blockchain
blockchain, err := builder.CreateBlockchain(ctx, &CreateParams{
Name: "get-test",
Type: TypeL1,
VMType: VMTypeEVM,
})
require.NoError(t, err)
t.Run("existing blockchain", func(t *testing.T) {
result, err := builder.GetBlockchain(blockchain.ID)
assert.NoError(t, err)
assert.Equal(t, blockchain, result)
})
t.Run("non-existent blockchain", func(t *testing.T) {
result, err := builder.GetBlockchain("non-existent")
assert.Error(t, err)
assert.Nil(t, result)
assert.Contains(t, err.Error(), "not found")
})
}
func TestBuilder_CreateChainConfig(t *testing.T) {
logger := log.NewNoOpLogger()
builder := NewBuilder(logger)
ctx := context.Background()
// Test default chain config generation
params := &CreateParams{
Name: "config-test",
Type: TypeL1,
VMType: VMTypeEVM,
ChainID: big.NewInt(77777),
VMConfig: map[string]interface{}{
"gasLimit": 15000000,
},
}
blockchain, err := builder.CreateBlockchain(ctx, params)
require.NoError(t, err)
// Verify the generated config
var config map[string]interface{}
err = json.Unmarshal(blockchain.ChainConfig, &config)
assert.NoError(t, err)
// Check chain ID
chainID, ok := config["chainId"].(float64)
assert.True(t, ok)
assert.Equal(t, float64(77777), chainID)
// Check consensus config
consensus, ok := config["consensus"].(map[string]interface{})
assert.True(t, ok)
assert.Equal(t, "lux", consensus["type"])
// Check VM config
vm, ok := config["vm"].(map[string]interface{})
assert.True(t, ok)
assert.Equal(t, "evm", vm["type"])
vmConfig, ok := vm["config"].(map[string]interface{})
assert.True(t, ok)
assert.Equal(t, float64(15000000), vmConfig["gasLimit"])
}