Files
mev-beta/orig/pkg/marketmanager/manager_test.go
Administrator 803de231ba feat: create v2-prep branch with comprehensive planning
Restructured project for V2 refactor:

**Structure Changes:**
- Moved all V1 code to orig/ folder (preserved with git mv)
- Created docs/planning/ directory
- Added orig/README_V1.md explaining V1 preservation

**Planning Documents:**
- 00_V2_MASTER_PLAN.md: Complete architecture overview
  - Executive summary of critical V1 issues
  - High-level component architecture diagrams
  - 5-phase implementation roadmap
  - Success metrics and risk mitigation

- 07_TASK_BREAKDOWN.md: Atomic task breakdown
  - 99+ hours of detailed tasks
  - Every task < 2 hours (atomic)
  - Clear dependencies and success criteria
  - Organized by implementation phase

**V2 Key Improvements:**
- Per-exchange parsers (factory pattern)
- Multi-layer strict validation
- Multi-index pool cache
- Background validation pipeline
- Comprehensive observability

**Critical Issues Addressed:**
- Zero address tokens (strict validation + cache enrichment)
- Parsing accuracy (protocol-specific parsers)
- No audit trail (background validation channel)
- Inefficient lookups (multi-index cache)
- Stats disconnection (event-driven metrics)

Next Steps:
1. Review planning documents
2. Begin Phase 1: Foundation (P1-001 through P1-010)
3. Implement parsers in Phase 2
4. Build cache system in Phase 3
5. Add validation pipeline in Phase 4
6. Migrate and test in Phase 5

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 10:14:26 +01:00

289 lines
9.2 KiB
Go

package marketmanager
import (
"math/big"
"testing"
"time"
"github.com/ethereum/go-ethereum/common"
)
func TestMarketManagerCreation(t *testing.T) {
config := &MarketManagerConfig{
VerificationWindow: 500 * time.Millisecond,
MaxMarkets: 1000,
}
manager := NewMarketManager(config)
if manager == nil {
t.Error("Expected MarketManager to be created")
}
if manager.verificationWindow != 500*time.Millisecond {
t.Errorf("Expected verificationWindow 500ms, got %v", manager.verificationWindow)
}
if manager.maxMarkets != 1000 {
t.Errorf("Expected maxMarkets 1000, got %d", manager.maxMarkets)
}
}
func TestMarketManagerAddAndGetMarket(t *testing.T) {
manager := NewMarketManager(&MarketManagerConfig{})
market := &Market{
Factory: common.HexToAddress("0x1F98431c8aD98523631AE4a59f267346ea31F984"),
PoolAddress: common.HexToAddress("0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"),
Token0: common.HexToAddress("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"),
Token1: common.HexToAddress("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"),
Fee: 3000,
Ticker: "USDC_WETH",
RawTicker: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48_0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
Key: "test_key",
Price: big.NewFloat(2000.5),
Protocol: "UniswapV3",
}
// Add market
err := manager.AddMarket(market)
if err != nil {
t.Errorf("Expected no error when adding market, got %v", err)
}
// Get market
retrievedMarket, err := manager.GetMarket(market.RawTicker, market.Key)
if err != nil {
t.Errorf("Expected no error when getting market, got %v", err)
}
if retrievedMarket.Ticker != market.Ticker {
t.Errorf("Expected ticker %s, got %s", market.Ticker, retrievedMarket.Ticker)
}
// Try to get non-existent market
_, err = manager.GetMarket("non_existent", "non_existent")
if err == nil {
t.Error("Expected error when getting non-existent market")
}
}
func TestMarketManagerGetMarketsByRawTicker(t *testing.T) {
manager := NewMarketManager(&MarketManagerConfig{})
// Add multiple markets with the same rawTicker
rawTicker := "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48_0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
market1 := &Market{
Factory: common.HexToAddress("0x1F98431c8aD98523631AE4a59f267346ea31F984"),
PoolAddress: common.HexToAddress("0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"),
Token0: common.HexToAddress("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"),
Token1: common.HexToAddress("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"),
Fee: 3000,
Ticker: "USDC_WETH_3000",
RawTicker: rawTicker,
Key: "test_key_1",
Price: big.NewFloat(2000.5),
Protocol: "UniswapV3",
}
market2 := &Market{
Factory: common.HexToAddress("0x1F98431c8aD98523631AE4a59f267346ea31F984"),
PoolAddress: common.HexToAddress("0x7BeA39867e4169DBe237d55C8242a8f2fDcD53F0"),
Token0: common.HexToAddress("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"),
Token1: common.HexToAddress("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"),
Fee: 500,
Ticker: "USDC_WETH_500",
RawTicker: rawTicker,
Key: "test_key_2",
Price: big.NewFloat(2001.0),
Protocol: "UniswapV3",
}
// Add markets
manager.AddMarket(market1)
manager.AddMarket(market2)
// Get markets by rawTicker
markets, err := manager.GetMarketsByRawTicker(rawTicker)
if err != nil {
t.Errorf("Expected no error when getting markets by rawTicker, got %v", err)
}
if len(markets) != 2 {
t.Errorf("Expected 2 markets, got %d", len(markets))
}
if markets[market1.Key].Ticker != market1.Ticker {
t.Errorf("Expected ticker %s, got %s", market1.Ticker, markets[market1.Key].Ticker)
}
if markets[market2.Key].Ticker != market2.Ticker {
t.Errorf("Expected ticker %s, got %s", market2.Ticker, markets[market2.Key].Ticker)
}
// Try to get markets for non-existent rawTicker
_, err = manager.GetMarketsByRawTicker("non_existent")
if err == nil {
t.Error("Expected error when getting markets for non-existent rawTicker")
}
}
func TestMarketManagerUpdateMarket(t *testing.T) {
manager := NewMarketManager(&MarketManagerConfig{})
market := &Market{
Factory: common.HexToAddress("0x1F98431c8aD98523631AE4a59f267346ea31F984"),
PoolAddress: common.HexToAddress("0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"),
Token0: common.HexToAddress("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"),
Token1: common.HexToAddress("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"),
Fee: 3000,
Ticker: "USDC_WETH",
RawTicker: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48_0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
Key: "test_key",
Price: big.NewFloat(2000.5),
Protocol: "UniswapV3",
}
// Add market
manager.AddMarket(market)
// Update market price
newPrice := big.NewFloat(2100.0)
market.Price = newPrice
// Update market
err := manager.UpdateMarket(market)
if err != nil {
t.Errorf("Expected no error when updating market, got %v", err)
}
// Get updated market
updatedMarket, err := manager.GetMarket(market.RawTicker, market.Key)
if err != nil {
t.Errorf("Expected no error when getting updated market, got %v", err)
}
if updatedMarket.Price.Cmp(newPrice) != 0 {
t.Errorf("Expected price %v, got %v", newPrice, updatedMarket.Price)
}
// Try to update non-existent market
nonExistentMarket := &Market{
RawTicker: "non_existent",
Key: "non_existent",
}
err = manager.UpdateMarket(nonExistentMarket)
if err == nil {
t.Error("Expected error when updating non-existent market")
}
}
func TestMarketManagerRemoveMarket(t *testing.T) {
manager := NewMarketManager(&MarketManagerConfig{})
market := &Market{
Factory: common.HexToAddress("0x1F98431c8aD98523631AE4a59f267346ea31F984"),
PoolAddress: common.HexToAddress("0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"),
Token0: common.HexToAddress("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"),
Token1: common.HexToAddress("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"),
Fee: 3000,
Ticker: "USDC_WETH",
RawTicker: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48_0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
Key: "test_key",
Price: big.NewFloat(2000.5),
Protocol: "UniswapV3",
}
// Add market
manager.AddMarket(market)
// Remove market
err := manager.RemoveMarket(market.RawTicker, market.Key)
if err != nil {
t.Errorf("Expected no error when removing market, got %v", err)
}
// Try to get removed market
_, err = manager.GetMarket(market.RawTicker, market.Key)
if err == nil {
t.Error("Expected error when getting removed market")
}
// Try to remove non-existent market
err = manager.RemoveMarket("non_existent", "non_existent")
if err == nil {
t.Error("Expected error when removing non-existent market")
}
}
func TestMarketManagerGetCounts(t *testing.T) {
manager := NewMarketManager(&MarketManagerConfig{})
// Initially should be zero
if manager.GetMarketCount() != 0 {
t.Errorf("Expected market count 0, got %d", manager.GetMarketCount())
}
if manager.GetRawTickerCount() != 0 {
t.Errorf("Expected raw ticker count 0, got %d", manager.GetRawTickerCount())
}
// Add markets
rawTicker1 := "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48_0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
rawTicker2 := "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48_0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599" // USDC_WBTC
market1 := &Market{
Factory: common.HexToAddress("0x1F98431c8aD98523631AE4a59f267346ea31F984"),
PoolAddress: common.HexToAddress("0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"),
Token0: common.HexToAddress("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"),
Token1: common.HexToAddress("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"),
Fee: 3000,
Ticker: "USDC_WETH_3000",
RawTicker: rawTicker1,
Key: "test_key_1",
Price: big.NewFloat(2000.5),
Protocol: "UniswapV3",
}
market2 := &Market{
Factory: common.HexToAddress("0x1F98431c8aD98523631AE4a59f267346ea31F984"),
PoolAddress: common.HexToAddress("0x7BeA39867e4169DBe237d55C8242a8f2fDcD53F0"),
Token0: common.HexToAddress("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"),
Token1: common.HexToAddress("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"),
Fee: 500,
Ticker: "USDC_WETH_500",
RawTicker: rawTicker1,
Key: "test_key_2",
Price: big.NewFloat(2001.0),
Protocol: "UniswapV3",
}
market3 := &Market{
Factory: common.HexToAddress("0x1F98431c8aD98523631AE4a59f267346ea31F984"),
PoolAddress: common.HexToAddress("0xC6962004f452bE9203591991D15f6b388e09E8D0"),
Token0: common.HexToAddress("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"),
Token1: common.HexToAddress("0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599"),
Fee: 3000,
Ticker: "USDC_WBTC",
RawTicker: rawTicker2,
Key: "test_key_3",
Price: big.NewFloat(50000.0),
Protocol: "UniswapV3",
}
manager.AddMarket(market1)
manager.AddMarket(market2)
manager.AddMarket(market3)
// Check counts
if manager.GetMarketCount() != 3 {
t.Errorf("Expected market count 3, got %d", manager.GetMarketCount())
}
if manager.GetRawTickerCount() != 2 {
t.Errorf("Expected raw ticker count 2, got %d", manager.GetRawTickerCount())
}
}