Files
mev-beta/pkg/market/manager_test.go

293 lines
8.2 KiB
Go

package market
import (
"context"
"testing"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/fraktal/mev-beta/internal/config"
"github.com/fraktal/mev-beta/internal/logger"
"github.com/holiman/uint256"
"github.com/stretchr/testify/assert"
)
func TestNewMarketManager(t *testing.T) {
// Create test config
cfg := &config.UniswapConfig{
Cache: config.CacheConfig{
Expiration: 300,
MaxSize: 10000,
},
}
// Create test logger
logger := logger.New("info", "text", "")
// Create market manager
manager := NewMarketManager(cfg, logger)
// Verify manager was created correctly
assert.NotNil(t, manager)
assert.Equal(t, cfg, manager.config)
assert.NotNil(t, manager.pools)
assert.Equal(t, time.Duration(cfg.Cache.Expiration)*time.Second, manager.cacheDuration)
assert.Equal(t, cfg.Cache.MaxSize, manager.maxCacheSize)
}
func TestGetPoolCacheHit(t *testing.T) {
// Create market manager
cfg := &config.UniswapConfig{
Cache: config.CacheConfig{
Expiration: 300,
MaxSize: 10000,
},
}
logger := logger.New("info", "text", "")
manager := NewMarketManager(cfg, logger)
// Add a pool to the cache
poolAddress := common.HexToAddress("0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640")
pool := &PoolData{
Address: 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(),
}
manager.pools[poolAddress.Hex()] = pool
// Get the pool (should be a cache hit)
ctx := context.Background()
result, err := manager.GetPool(ctx, poolAddress)
// Verify results
assert.NoError(t, err)
assert.Equal(t, pool, result)
}
func TestGetPoolCacheMiss(t *testing.T) {
// Create market manager
cfg := &config.UniswapConfig{
Cache: config.CacheConfig{
Expiration: 300,
MaxSize: 10000,
},
}
logger := logger.New("info", "text", "")
manager := NewMarketManager(cfg, logger)
// Get a pool that's not in the cache (should trigger fetch)
poolAddress := common.HexToAddress("0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640")
ctx := context.Background()
result, err := manager.GetPool(ctx, poolAddress)
// Verify results (should get mock data)
assert.NoError(t, err)
assert.NotNil(t, result)
assert.Equal(t, poolAddress, result.Address)
assert.Equal(t, "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", result.Token0.Hex())
assert.Equal(t, "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", result.Token1.Hex())
}
func TestGetPoolsByTokens(t *testing.T) {
// Create market manager
cfg := &config.UniswapConfig{
Cache: config.CacheConfig{
Expiration: 300,
MaxSize: 10000,
},
}
logger := logger.New("info", "text", "")
manager := NewMarketManager(cfg, logger)
// Add some pools to the cache
token0 := common.HexToAddress("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48") // USDC
token1 := common.HexToAddress("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2") // WETH
pool1 := &PoolData{
Address: common.HexToAddress("0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"),
Token0: token0,
Token1: token1,
Fee: 3000,
}
manager.pools[pool1.Address.Hex()] = pool1
pool2 := &PoolData{
Address: common.HexToAddress("0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc"),
Token0: token0,
Token1: token1,
Fee: 500,
}
manager.pools[pool2.Address.Hex()] = pool2
// Add a pool with different tokens
token2 := common.HexToAddress("0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984") // UNI
pool3 := &PoolData{
Address: common.HexToAddress("0x1234567890123456789012345678901234567890"),
Token0: token0,
Token1: token2,
Fee: 3000,
}
manager.pools[pool3.Address.Hex()] = pool3
// Get pools for the token pair
pools := manager.GetPoolsByTokens(token0, token1)
// Verify results
assert.Len(t, pools, 2)
// Check that both pools are in the result
pool1Found := false
pool2Found := false
for _, pool := range pools {
if pool.Address == pool1.Address {
pool1Found = true
}
if pool.Address == pool2.Address {
pool2Found = true
}
}
assert.True(t, pool1Found)
assert.True(t, pool2Found)
}
func TestGetAllPools(t *testing.T) {
// Create market manager
cfg := &config.UniswapConfig{
Cache: config.CacheConfig{
Expiration: 300,
MaxSize: 10000,
},
}
logger := logger.New("info", "text", "")
manager := NewMarketManager(cfg, logger)
// Add some pools to the cache
pool1 := &PoolData{
Address: common.HexToAddress("0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"),
Token0: common.HexToAddress("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"),
Token1: common.HexToAddress("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"),
Fee: 3000,
}
manager.pools[pool1.Address.Hex()] = pool1
pool2 := &PoolData{
Address: common.HexToAddress("0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc"),
Token0: common.HexToAddress("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"),
Token1: common.HexToAddress("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"),
Fee: 500,
}
manager.pools[pool2.Address.Hex()] = pool2
// Get all pools
pools := manager.GetAllPools()
// Verify results
assert.Len(t, pools, 2)
}
func TestUpdatePoolExisting(t *testing.T) {
// Create market manager
cfg := &config.UniswapConfig{
Cache: config.CacheConfig{
Expiration: 300,
MaxSize: 10000,
},
}
logger := logger.New("info", "text", "")
manager := NewMarketManager(cfg, logger)
// Add a pool to the cache
poolAddress := common.HexToAddress("0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640")
originalLiquidity := uint256.NewInt(1000000000000000000)
originalSqrtPrice := uint256.NewInt(2505414483750470000)
originalTick := 200000
pool := &PoolData{
Address: poolAddress,
Liquidity: originalLiquidity,
SqrtPriceX96: originalSqrtPrice,
Tick: originalTick,
LastUpdated: time.Now().Add(-time.Hour), // Set to past time
}
manager.pools[poolAddress.Hex()] = pool
// Update the pool
newLiquidity := uint256.NewInt(2000000000000000000)
newSqrtPrice := uint256.NewInt(3000000000000000000)
newTick := 250000
manager.UpdatePool(poolAddress, newLiquidity, newSqrtPrice, newTick)
// Verify the pool was updated
updatedPool := manager.pools[poolAddress.Hex()]
assert.Equal(t, newLiquidity, updatedPool.Liquidity)
assert.Equal(t, newSqrtPrice, updatedPool.SqrtPriceX96)
assert.Equal(t, newTick, updatedPool.Tick)
// Check that the last updated time is more recent (allowing for small time differences)
assert.True(t, updatedPool.LastUpdated.Unix() >= pool.LastUpdated.Unix())
}
func TestUpdatePoolNew(t *testing.T) {
// Create market manager
cfg := &config.UniswapConfig{
Cache: config.CacheConfig{
Expiration: 300,
MaxSize: 10000,
},
}
logger := logger.New("info", "text", "")
manager := NewMarketManager(cfg, logger)
// Update a pool that doesn't exist yet
poolAddress := common.HexToAddress("0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640")
liquidity := uint256.NewInt(1000000000000000000)
sqrtPrice := uint256.NewInt(2505414483750470000)
tick := 200000
manager.UpdatePool(poolAddress, liquidity, sqrtPrice, tick)
// Verify the pool was created
createdPool := manager.pools[poolAddress.Hex()]
assert.NotNil(t, createdPool)
assert.Equal(t, poolAddress, createdPool.Address)
assert.Equal(t, liquidity, createdPool.Liquidity)
assert.Equal(t, sqrtPrice, createdPool.SqrtPriceX96)
assert.Equal(t, tick, createdPool.Tick)
}
func TestGetCacheStats(t *testing.T) {
// Create market manager
cfg := &config.UniswapConfig{
Cache: config.CacheConfig{
Expiration: 300,
MaxSize: 10000,
},
}
logger := logger.New("info", "text", "")
manager := NewMarketManager(cfg, logger)
// Add some pools to the cache
pool1 := &PoolData{
Address: common.HexToAddress("0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"),
}
manager.pools[pool1.Address.Hex()] = pool1
pool2 := &PoolData{
Address: common.HexToAddress("0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc"),
}
manager.pools[pool2.Address.Hex()] = pool2
// Get cache stats
currentSize, maxSize := manager.GetCacheStats()
// Verify results
assert.Equal(t, 2, currentSize)
assert.Equal(t, 10000, maxSize)
}