mirror of
https://github.com/luxfi/dex.git
synced 2026-09-24 00:26:31 +00:00
472 lines
13 KiB
Go
472 lines
13 KiB
Go
package lx
|
|
|
|
import (
|
|
"math/big"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
// TestXChainIntegration tests X-Chain integration functions
|
|
func TestXChainIntegration(t *testing.T) {
|
|
t.Run("CreateXChainIntegration", func(t *testing.T) {
|
|
integration := &XChainIntegration{
|
|
chainID: 1,
|
|
contractAddr: "0x1234567890abcdef",
|
|
settledOrders: make(map[uint64]*SettledOrder),
|
|
pendingBatches: make(map[uint64]*SettlementBatch),
|
|
}
|
|
|
|
assert.NotNil(t, integration)
|
|
assert.Equal(t, uint64(1), integration.chainID)
|
|
assert.Equal(t, "0x1234567890abcdef", integration.contractAddr)
|
|
assert.NotNil(t, integration.settledOrders)
|
|
assert.NotNil(t, integration.pendingBatches)
|
|
})
|
|
|
|
t.Run("SettlementBatch", func(t *testing.T) {
|
|
batch := &SettlementBatch{
|
|
BatchID: 1,
|
|
Timestamp: time.Now(),
|
|
Orders: make([]*Order, 0),
|
|
Status: SettlementPending,
|
|
}
|
|
|
|
assert.Equal(t, uint64(1), batch.BatchID)
|
|
assert.Equal(t, SettlementPending, batch.Status)
|
|
assert.NotNil(t, batch.Orders)
|
|
})
|
|
|
|
t.Run("SettledOrder", func(t *testing.T) {
|
|
order := &SettledOrder{
|
|
OrderID: 1,
|
|
TxHash: "0xabcdef",
|
|
BlockNumber: 100,
|
|
SettlementTime: time.Now(),
|
|
GasUsed: big.NewInt(21000),
|
|
}
|
|
|
|
assert.Equal(t, uint64(1), order.OrderID)
|
|
assert.Equal(t, "0xabcdef", order.TxHash)
|
|
assert.Equal(t, uint64(100), order.BlockNumber)
|
|
assert.Equal(t, big.NewInt(21000), order.GasUsed)
|
|
})
|
|
|
|
t.Run("XChainConfig", func(t *testing.T) {
|
|
config := &XChainConfig{
|
|
RPC: "https://api.lux.network",
|
|
ChainID: 1,
|
|
SettlementContract: "0x1234567890abcdef",
|
|
BatchSize: 100,
|
|
BatchTimeout: 5 * time.Second,
|
|
MaxGasPrice: big.NewInt(100000000000), // 100 gwei
|
|
}
|
|
|
|
assert.Equal(t, "https://api.lux.network", config.RPC)
|
|
assert.Equal(t, uint64(1), config.ChainID)
|
|
assert.Equal(t, "0x1234567890abcdef", config.SettlementContract)
|
|
assert.Equal(t, 100, config.BatchSize)
|
|
assert.Equal(t, 5*time.Second, config.BatchTimeout)
|
|
assert.Equal(t, big.NewInt(100000000000), config.MaxGasPrice)
|
|
})
|
|
|
|
t.Run("XChainStats", func(t *testing.T) {
|
|
stats := &XChainStats{
|
|
TotalSettled: 1000,
|
|
TotalPending: 50,
|
|
TotalFailed: 5,
|
|
AvgGasUsed: big.NewInt(50000),
|
|
AvgSettlementTime: 2 * time.Second,
|
|
LastSettlement: time.Now(),
|
|
}
|
|
|
|
assert.Equal(t, uint64(1000), stats.TotalSettled)
|
|
assert.Equal(t, uint64(50), stats.TotalPending)
|
|
assert.Equal(t, uint64(5), stats.TotalFailed)
|
|
assert.Equal(t, big.NewInt(50000), stats.AvgGasUsed)
|
|
assert.Equal(t, 2*time.Second, stats.AvgSettlementTime)
|
|
})
|
|
}
|
|
|
|
// TestXChainSettlement tests settlement functionality
|
|
func TestXChainSettlement(t *testing.T) {
|
|
t.Run("CreateSettlementEngine", func(t *testing.T) {
|
|
engine := &SettlementEngine{
|
|
batches: make(map[uint64]*SettlementBatch),
|
|
pendingOrders: make([]*Order, 0),
|
|
batchSize: 100,
|
|
batchTimeout: 5 * time.Second,
|
|
}
|
|
|
|
assert.NotNil(t, engine)
|
|
assert.NotNil(t, engine.batches)
|
|
assert.NotNil(t, engine.pendingOrders)
|
|
assert.Equal(t, 100, engine.batchSize)
|
|
assert.Equal(t, 5*time.Second, engine.batchTimeout)
|
|
})
|
|
|
|
t.Run("AddOrderToBatch", func(t *testing.T) {
|
|
engine := &SettlementEngine{
|
|
batches: make(map[uint64]*SettlementBatch),
|
|
pendingOrders: make([]*Order, 0),
|
|
batchSize: 2,
|
|
batchTimeout: 5 * time.Second,
|
|
}
|
|
|
|
order1 := &Order{ID: 1, Symbol: "BTC-USD", Price: 50000, Size: 1}
|
|
order2 := &Order{ID: 2, Symbol: "ETH-USD", Price: 3000, Size: 10}
|
|
|
|
engine.pendingOrders = append(engine.pendingOrders, order1)
|
|
assert.Len(t, engine.pendingOrders, 1)
|
|
|
|
engine.pendingOrders = append(engine.pendingOrders, order2)
|
|
assert.Len(t, engine.pendingOrders, 2)
|
|
})
|
|
|
|
t.Run("ProcessSettlement", func(t *testing.T) {
|
|
batch := &SettlementBatch{
|
|
BatchID: 1,
|
|
Timestamp: time.Now(),
|
|
Orders: make([]*Order, 0),
|
|
Status: SettlementPending,
|
|
}
|
|
|
|
// Add some orders
|
|
order1 := &Order{ID: 1, Symbol: "BTC-USD", Price: 50000, Size: 1}
|
|
order2 := &Order{ID: 2, Symbol: "ETH-USD", Price: 3000, Size: 10}
|
|
batch.Orders = append(batch.Orders, order1, order2)
|
|
|
|
assert.Len(t, batch.Orders, 2)
|
|
assert.Equal(t, SettlementPending, batch.Status)
|
|
|
|
// Simulate processing
|
|
batch.Status = SettlementProcessing
|
|
assert.Equal(t, SettlementProcessing, batch.Status)
|
|
|
|
// Simulate completion
|
|
batch.Status = SettlementComplete
|
|
assert.Equal(t, SettlementComplete, batch.Status)
|
|
})
|
|
}
|
|
|
|
// TestClearingEngine tests the clearing engine
|
|
func TestClearingEngine(t *testing.T) {
|
|
t.Run("CreateClearingEngine", func(t *testing.T) {
|
|
engine := &ClearingEngine{
|
|
positions: make(map[string]map[string]*Position),
|
|
balances: make(map[string]*Balance),
|
|
marginRequirements: make(map[string]*MarginRequirement),
|
|
}
|
|
|
|
assert.NotNil(t, engine)
|
|
assert.NotNil(t, engine.positions)
|
|
assert.NotNil(t, engine.balances)
|
|
assert.NotNil(t, engine.marginRequirements)
|
|
})
|
|
|
|
t.Run("Position", func(t *testing.T) {
|
|
pos := &Position{
|
|
Symbol: "BTC-USD",
|
|
User: "user1",
|
|
Size: 1.5,
|
|
EntryPrice: 50000,
|
|
MarkPrice: 51000,
|
|
UnrealizedPnL: 1500,
|
|
RealizedPnL: 0,
|
|
}
|
|
|
|
assert.Equal(t, "BTC-USD", pos.Symbol)
|
|
assert.Equal(t, "user1", pos.User)
|
|
assert.Equal(t, 1.5, pos.Size)
|
|
assert.Equal(t, 50000.0, pos.EntryPrice)
|
|
assert.Equal(t, 51000.0, pos.MarkPrice)
|
|
assert.Equal(t, 1500.0, pos.UnrealizedPnL)
|
|
})
|
|
|
|
t.Run("Balance", func(t *testing.T) {
|
|
balance := &Balance{
|
|
User: "user1",
|
|
Available: big.NewInt(100000),
|
|
Locked: big.NewInt(50000),
|
|
Total: big.NewInt(150000),
|
|
LastUpdate: time.Now(),
|
|
}
|
|
|
|
assert.Equal(t, "user1", balance.User)
|
|
assert.Equal(t, big.NewInt(100000), balance.Available)
|
|
assert.Equal(t, big.NewInt(50000), balance.Locked)
|
|
assert.Equal(t, big.NewInt(150000), balance.Total)
|
|
})
|
|
|
|
t.Run("MarginRequirement", func(t *testing.T) {
|
|
margin := &MarginRequirement{
|
|
User: "user1",
|
|
InitialMargin: big.NewInt(10000),
|
|
MaintenanceMargin: big.NewInt(5000),
|
|
MarginRatio: 0.2,
|
|
LastCalculation: time.Now(),
|
|
}
|
|
|
|
assert.Equal(t, "user1", margin.User)
|
|
assert.Equal(t, big.NewInt(10000), margin.InitialMargin)
|
|
assert.Equal(t, big.NewInt(5000), margin.MaintenanceMargin)
|
|
assert.Equal(t, 0.2, margin.MarginRatio)
|
|
})
|
|
}
|
|
|
|
// TestXChainEvents tests X-Chain event handling
|
|
func TestXChainEvents(t *testing.T) {
|
|
t.Run("OrderSettledEvent", func(t *testing.T) {
|
|
event := &OrderSettledEvent{
|
|
OrderID: 1,
|
|
TxHash: "0xabcdef",
|
|
BlockNumber: 100,
|
|
Timestamp: time.Now(),
|
|
}
|
|
|
|
assert.Equal(t, uint64(1), event.OrderID)
|
|
assert.Equal(t, "0xabcdef", event.TxHash)
|
|
assert.Equal(t, uint64(100), event.BlockNumber)
|
|
})
|
|
|
|
t.Run("BatchSettledEvent", func(t *testing.T) {
|
|
event := &BatchSettledEvent{
|
|
BatchID: 1,
|
|
TxHash: "0xabcdef",
|
|
OrderCount: 10,
|
|
TotalVolume: big.NewInt(1000000),
|
|
Timestamp: time.Now(),
|
|
}
|
|
|
|
assert.Equal(t, uint64(1), event.BatchID)
|
|
assert.Equal(t, "0xabcdef", event.TxHash)
|
|
assert.Equal(t, 10, event.OrderCount)
|
|
assert.Equal(t, big.NewInt(1000000), event.TotalVolume)
|
|
})
|
|
|
|
t.Run("SettlementFailedEvent", func(t *testing.T) {
|
|
event := &SettlementFailedEvent{
|
|
BatchID: 1,
|
|
Reason: "insufficient gas",
|
|
Timestamp: time.Now(),
|
|
}
|
|
|
|
assert.Equal(t, uint64(1), event.BatchID)
|
|
assert.Equal(t, "insufficient gas", event.Reason)
|
|
})
|
|
}
|
|
|
|
// TestXChainOracle tests oracle integration
|
|
func TestXChainOracle(t *testing.T) {
|
|
t.Run("OraclePrice", func(t *testing.T) {
|
|
price := &OraclePrice{
|
|
Symbol: "BTC-USD",
|
|
Price: 50000,
|
|
Timestamp: time.Now(),
|
|
Source: "chainlink",
|
|
}
|
|
|
|
assert.Equal(t, "BTC-USD", price.Symbol)
|
|
assert.Equal(t, 50000.0, price.Price)
|
|
assert.Equal(t, "chainlink", price.Source)
|
|
})
|
|
|
|
t.Run("OracleUpdate", func(t *testing.T) {
|
|
update := &OracleUpdate{
|
|
Prices: map[string]float64{
|
|
"BTC-USD": 50000,
|
|
"ETH-USD": 3000,
|
|
"SOL-USD": 100,
|
|
},
|
|
Timestamp: time.Now(),
|
|
Signature: "0xsignature",
|
|
}
|
|
|
|
assert.Len(t, update.Prices, 3)
|
|
assert.Equal(t, 50000.0, update.Prices["BTC-USD"])
|
|
assert.Equal(t, 3000.0, update.Prices["ETH-USD"])
|
|
assert.Equal(t, 100.0, update.Prices["SOL-USD"])
|
|
assert.Equal(t, "0xsignature", update.Signature)
|
|
})
|
|
}
|
|
|
|
// TestXChainGasOptimization tests gas optimization
|
|
func TestXChainGasOptimization(t *testing.T) {
|
|
t.Run("GasEstimator", func(t *testing.T) {
|
|
estimator := &GasEstimator{
|
|
baseGas: 21000,
|
|
perOrderGas: 50000,
|
|
maxGasPrice: big.NewInt(100000000000), // 100 gwei
|
|
priorityFee: big.NewInt(2000000000), // 2 gwei
|
|
}
|
|
|
|
assert.Equal(t, uint64(21000), estimator.baseGas)
|
|
assert.Equal(t, uint64(50000), estimator.perOrderGas)
|
|
assert.Equal(t, big.NewInt(100000000000), estimator.maxGasPrice)
|
|
assert.Equal(t, big.NewInt(2000000000), estimator.priorityFee)
|
|
})
|
|
|
|
t.Run("EstimateGas", func(t *testing.T) {
|
|
estimator := &GasEstimator{
|
|
baseGas: 21000,
|
|
perOrderGas: 50000,
|
|
}
|
|
|
|
// Estimate for 10 orders
|
|
orderCount := 10
|
|
expectedGas := estimator.baseGas + uint64(orderCount)*estimator.perOrderGas
|
|
assert.Equal(t, uint64(521000), expectedGas)
|
|
})
|
|
|
|
t.Run("GasOptimization", func(t *testing.T) {
|
|
optimizer := &GasOptimizer{
|
|
batchSize: 100,
|
|
maxBatchGas: 3000000,
|
|
targetGasPrice: big.NewInt(50000000000), // 50 gwei
|
|
}
|
|
|
|
assert.Equal(t, 100, optimizer.batchSize)
|
|
assert.Equal(t, uint64(3000000), optimizer.maxBatchGas)
|
|
assert.Equal(t, big.NewInt(50000000000), optimizer.targetGasPrice)
|
|
})
|
|
}
|
|
|
|
// TestXChainSecurity tests security features
|
|
func TestXChainSecurity(t *testing.T) {
|
|
t.Run("SignatureVerification", func(t *testing.T) {
|
|
sig := &Signature{
|
|
V: 27,
|
|
R: "0xr",
|
|
S: "0xs",
|
|
}
|
|
|
|
assert.Equal(t, uint8(27), sig.V)
|
|
assert.Equal(t, "0xr", sig.R)
|
|
assert.Equal(t, "0xs", sig.S)
|
|
})
|
|
|
|
t.Run("NonceManager", func(t *testing.T) {
|
|
manager := &NonceManager{
|
|
currentNonce: 100,
|
|
pendingNonces: make(map[uint64]bool),
|
|
}
|
|
|
|
assert.Equal(t, uint64(100), manager.currentNonce)
|
|
assert.NotNil(t, manager.pendingNonces)
|
|
|
|
// Get next nonce
|
|
manager.currentNonce++
|
|
assert.Equal(t, uint64(101), manager.currentNonce)
|
|
})
|
|
|
|
t.Run("AccessControl", func(t *testing.T) {
|
|
acl := &AccessControl{
|
|
admins: map[string]bool{"admin1": true},
|
|
operators: map[string]bool{"op1": true, "op2": true},
|
|
blacklist: map[string]bool{"bad1": true},
|
|
}
|
|
|
|
assert.True(t, acl.admins["admin1"])
|
|
assert.True(t, acl.operators["op1"])
|
|
assert.True(t, acl.blacklist["bad1"])
|
|
})
|
|
}
|
|
|
|
// TestXChainMonitoring tests monitoring and metrics
|
|
func TestXChainMonitoring(t *testing.T) {
|
|
t.Run("Metrics", func(t *testing.T) {
|
|
metrics := &XChainMetrics{
|
|
SettlementLatency: 2 * time.Second,
|
|
GasUsedTotal: big.NewInt(10000000),
|
|
SuccessRate: 0.99,
|
|
FailureCount: 10,
|
|
LastUpdate: time.Now(),
|
|
}
|
|
|
|
assert.Equal(t, 2*time.Second, metrics.SettlementLatency)
|
|
assert.Equal(t, big.NewInt(10000000), metrics.GasUsedTotal)
|
|
assert.Equal(t, 0.99, metrics.SuccessRate)
|
|
assert.Equal(t, uint64(10), metrics.FailureCount)
|
|
})
|
|
|
|
t.Run("HealthCheck", func(t *testing.T) {
|
|
health := &HealthCheck{
|
|
Status: "healthy",
|
|
BlockHeight: 1000000,
|
|
PeerCount: 8,
|
|
Syncing: false,
|
|
LastCheck: time.Now(),
|
|
}
|
|
|
|
assert.Equal(t, "healthy", health.Status)
|
|
assert.Equal(t, uint64(1000000), health.BlockHeight)
|
|
assert.Equal(t, 8, health.PeerCount)
|
|
assert.False(t, health.Syncing)
|
|
})
|
|
|
|
t.Run("AlertSystem", func(t *testing.T) {
|
|
alert := &Alert{
|
|
Level: "critical",
|
|
Message: "Settlement failure rate exceeded threshold",
|
|
Timestamp: time.Now(),
|
|
Resolved: false,
|
|
}
|
|
|
|
assert.Equal(t, "critical", alert.Level)
|
|
assert.Contains(t, alert.Message, "Settlement failure")
|
|
assert.False(t, alert.Resolved)
|
|
})
|
|
}
|
|
|
|
// TestXChainRecovery tests recovery mechanisms
|
|
func TestXChainRecovery(t *testing.T) {
|
|
t.Run("RecoveryManager", func(t *testing.T) {
|
|
manager := &RecoveryManager{
|
|
failedBatches: make(map[uint64]*SettlementBatch),
|
|
retryAttempts: make(map[uint64]int),
|
|
maxRetries: 3,
|
|
retryDelay: 30 * time.Second,
|
|
}
|
|
|
|
assert.NotNil(t, manager.failedBatches)
|
|
assert.NotNil(t, manager.retryAttempts)
|
|
assert.Equal(t, 3, manager.maxRetries)
|
|
assert.Equal(t, 30*time.Second, manager.retryDelay)
|
|
})
|
|
|
|
t.Run("RetryPolicy", func(t *testing.T) {
|
|
policy := &RetryPolicy{
|
|
MaxAttempts: 3,
|
|
InitialDelay: 1 * time.Second,
|
|
MaxDelay: 30 * time.Second,
|
|
BackoffFactor: 2.0,
|
|
}
|
|
|
|
assert.Equal(t, 3, policy.MaxAttempts)
|
|
assert.Equal(t, 1*time.Second, policy.InitialDelay)
|
|
assert.Equal(t, 30*time.Second, policy.MaxDelay)
|
|
assert.Equal(t, 2.0, policy.BackoffFactor)
|
|
})
|
|
|
|
t.Run("DisasterRecovery", func(t *testing.T) {
|
|
dr := &DisasterRecovery{
|
|
backupEndpoints: []string{
|
|
"https://backup1.lux.network",
|
|
"https://backup2.lux.network",
|
|
},
|
|
currentEndpoint: 0,
|
|
lastSwitch: time.Now(),
|
|
}
|
|
|
|
assert.Len(t, dr.backupEndpoints, 2)
|
|
assert.Equal(t, 0, dr.currentEndpoint)
|
|
|
|
// Switch endpoint
|
|
dr.currentEndpoint = (dr.currentEndpoint + 1) % len(dr.backupEndpoints)
|
|
assert.Equal(t, 1, dr.currentEndpoint)
|
|
})
|
|
}
|
|
|
|
// Test-specific helper structures can go here if needed
|