Update module name to github.com/fraktal/mev-beta and fix channel closing issues in pipeline stages
This commit is contained in:
213
pkg/scanner/concurrent_test.go
Normal file
213
pkg/scanner/concurrent_test.go
Normal file
@@ -0,0 +1,213 @@
|
||||
package scanner
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/fraktal/mev-beta/internal/config"
|
||||
"github.com/fraktal/mev-beta/internal/logger"
|
||||
"github.com/fraktal/mev-beta/pkg/events"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/holiman/uint256"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestNewMarketScanner(t *testing.T) {
|
||||
// Create test config
|
||||
cfg := &config.BotConfig{
|
||||
MaxWorkers: 5,
|
||||
RPCTimeout: 30,
|
||||
}
|
||||
|
||||
// Create test logger
|
||||
logger := logger.New("info", "text", "")
|
||||
|
||||
// Create market scanner
|
||||
scanner := NewMarketScanner(cfg, logger)
|
||||
|
||||
// Verify scanner was created correctly
|
||||
assert.NotNil(t, scanner)
|
||||
assert.Equal(t, cfg, scanner.config)
|
||||
assert.Equal(t, logger, scanner.logger)
|
||||
assert.NotNil(t, scanner.workerPool)
|
||||
assert.NotNil(t, scanner.workers)
|
||||
assert.NotNil(t, scanner.cache)
|
||||
assert.NotNil(t, scanner.cacheTTL)
|
||||
assert.Equal(t, time.Duration(cfg.RPCTimeout)*time.Second, scanner.cacheTTL)
|
||||
assert.Equal(t, cfg.MaxWorkers, len(scanner.workers))
|
||||
}
|
||||
|
||||
func TestEventTypeString(t *testing.T) {
|
||||
// Test all event types
|
||||
assert.Equal(t, "Unknown", events.Unknown.String())
|
||||
assert.Equal(t, "Swap", events.Swap.String())
|
||||
assert.Equal(t, "AddLiquidity", events.AddLiquidity.String())
|
||||
assert.Equal(t, "RemoveLiquidity", events.RemoveLiquidity.String())
|
||||
assert.Equal(t, "NewPool", events.NewPool.String())
|
||||
}
|
||||
|
||||
func TestIsSignificantMovement(t *testing.T) {
|
||||
// Create market scanner
|
||||
cfg := &config.BotConfig{
|
||||
MinProfitThreshold: 10.0,
|
||||
}
|
||||
logger := logger.New("info", "text", "")
|
||||
scanner := NewMarketScanner(cfg, logger)
|
||||
|
||||
// Test significant movement
|
||||
movement := &PriceMovement{
|
||||
PriceImpact: 15.0, // Above threshold
|
||||
}
|
||||
assert.True(t, scanner.isSignificantMovement(movement, cfg.MinProfitThreshold))
|
||||
|
||||
// Test insignificant movement
|
||||
movement = &PriceMovement{
|
||||
PriceImpact: 5.0, // Below threshold
|
||||
}
|
||||
assert.False(t, scanner.isSignificantMovement(movement, cfg.MinProfitThreshold))
|
||||
}
|
||||
|
||||
func TestCalculatePriceMovement(t *testing.T) {
|
||||
// Create market scanner
|
||||
cfg := &config.BotConfig{}
|
||||
logger := logger.New("info", "text", "")
|
||||
scanner := NewMarketScanner(cfg, logger)
|
||||
|
||||
// Create test event
|
||||
event := EventDetails{
|
||||
Token0: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
||||
Token1: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
|
||||
Amount0In: big.NewInt(1000000000), // 1000 tokens
|
||||
Amount0Out: big.NewInt(0),
|
||||
Amount1In: big.NewInt(0),
|
||||
Amount1Out: big.NewInt(500000000000000000), // 0.5 ETH
|
||||
Tick: 200000,
|
||||
Timestamp: time.Now(),
|
||||
}
|
||||
|
||||
// Create test pool data
|
||||
poolData := &CachedData{
|
||||
SqrtPriceX96: uint256.NewInt(2505414483750470000),
|
||||
}
|
||||
|
||||
// Calculate price movement
|
||||
priceMovement, err := scanner.calculatePriceMovement(event, poolData)
|
||||
|
||||
// Verify results
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, priceMovement)
|
||||
assert.Equal(t, event.Token0, priceMovement.Token0)
|
||||
assert.Equal(t, event.Token1, priceMovement.Token1)
|
||||
assert.Equal(t, event.Tick, priceMovement.TickBefore)
|
||||
assert.Equal(t, event.Timestamp, priceMovement.Timestamp)
|
||||
assert.NotNil(t, priceMovement.PriceBefore)
|
||||
assert.NotNil(t, priceMovement.AmountIn)
|
||||
assert.NotNil(t, priceMovement.AmountOut)
|
||||
}
|
||||
|
||||
func TestFindArbitrageOpportunities(t *testing.T) {
|
||||
// Create market scanner
|
||||
cfg := &config.BotConfig{}
|
||||
logger := logger.New("info", "text", "")
|
||||
scanner := NewMarketScanner(cfg, logger)
|
||||
|
||||
// Create test event
|
||||
event := EventDetails{
|
||||
PoolAddress: "0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640",
|
||||
Token0: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
||||
Token1: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
|
||||
Protocol: "UniswapV3",
|
||||
}
|
||||
|
||||
// Create test price movement
|
||||
movement := &PriceMovement{
|
||||
Token0: event.Token0,
|
||||
Token1: event.Token1,
|
||||
Pool: event.PoolAddress,
|
||||
Protocol: event.Protocol,
|
||||
PriceImpact: 5.0,
|
||||
Timestamp: time.Now(),
|
||||
}
|
||||
|
||||
// Find arbitrage opportunities (should return mock opportunities)
|
||||
opportunities := scanner.findArbitrageOpportunities(event, movement)
|
||||
|
||||
// Verify results
|
||||
assert.NotNil(t, opportunities)
|
||||
assert.Len(t, opportunities, 1)
|
||||
assert.Equal(t, []string{event.Token0, event.Token1}, opportunities[0].Path)
|
||||
assert.Contains(t, opportunities[0].Pools, event.PoolAddress)
|
||||
assert.Equal(t, event.Protocol, opportunities[0].Protocol)
|
||||
assert.NotNil(t, opportunities[0].Profit)
|
||||
assert.NotNil(t, opportunities[0].GasEstimate)
|
||||
assert.Equal(t, 5.0, opportunities[0].ROI)
|
||||
}
|
||||
|
||||
func TestGetPoolDataCacheHit(t *testing.T) {
|
||||
// Create market scanner
|
||||
cfg := &config.BotConfig{
|
||||
RPCTimeout: 30,
|
||||
}
|
||||
logger := logger.New("info", "text", "")
|
||||
scanner := NewMarketScanner(cfg, logger)
|
||||
|
||||
// Add pool data to cache
|
||||
poolAddress := "0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"
|
||||
poolData := &CachedData{
|
||||
Address: common.HexToAddress(poolAddress),
|
||||
Token0: common.HexToAddress("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"),
|
||||
Token1: common.HexToAddress("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"),
|
||||
Fee: 3000,
|
||||
Liquidity: uint256.NewInt(1000000000000000000),
|
||||
SqrtPriceX96: uint256.NewInt(2505414483750470000),
|
||||
Tick: 200000,
|
||||
TickSpacing: 60,
|
||||
LastUpdated: time.Now(),
|
||||
}
|
||||
scanner.cacheMutex.Lock()
|
||||
scanner.cache["pool_"+poolAddress] = poolData
|
||||
scanner.cacheMutex.Unlock()
|
||||
|
||||
// Get pool data (should be cache hit)
|
||||
result, err := scanner.getPoolData(poolAddress)
|
||||
|
||||
// Verify results
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, poolData, result)
|
||||
}
|
||||
|
||||
func TestUpdatePoolData(t *testing.T) {
|
||||
// Create market scanner
|
||||
cfg := &config.BotConfig{}
|
||||
logger := logger.New("info", "text", "")
|
||||
scanner := NewMarketScanner(cfg, logger)
|
||||
|
||||
// Create test event
|
||||
event := EventDetails{
|
||||
PoolAddress: "0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640",
|
||||
Token0: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
||||
Token1: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
|
||||
Liquidity: uint256.NewInt(1000000000000000000),
|
||||
SqrtPriceX96: uint256.NewInt(2505414483750470000),
|
||||
Tick: 200000,
|
||||
Timestamp: time.Now(),
|
||||
}
|
||||
|
||||
// Update pool data
|
||||
scanner.updatePoolData(event)
|
||||
|
||||
// Verify the pool data was updated
|
||||
scanner.cacheMutex.RLock()
|
||||
poolData, exists := scanner.cache["pool_"+event.PoolAddress]
|
||||
scanner.cacheMutex.RUnlock()
|
||||
|
||||
assert.True(t, exists)
|
||||
assert.NotNil(t, poolData)
|
||||
assert.Equal(t, common.HexToAddress(event.PoolAddress), poolData.Address)
|
||||
assert.Equal(t, common.HexToAddress(event.Token0), poolData.Token0)
|
||||
assert.Equal(t, common.HexToAddress(event.Token1), poolData.Token1)
|
||||
assert.Equal(t, event.Liquidity, poolData.Liquidity)
|
||||
assert.Equal(t, event.SqrtPriceX96, poolData.SqrtPriceX96)
|
||||
assert.Equal(t, event.Tick, poolData.Tick)
|
||||
}
|
||||
Reference in New Issue
Block a user