package e2e import ( "context" "math/big" "testing" "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/fraktal/mev-beta/internal/config" "github.com/fraktal/mev-beta/internal/logger" "github.com/fraktal/mev-beta/internal/ratelimit" "github.com/fraktal/mev-beta/pkg/market" "github.com/fraktal/mev-beta/pkg/monitor" "github.com/fraktal/mev-beta/pkg/scanner" "github.com/stretchr/testify/assert" ) func TestEndToEndPipeline(t *testing.T) { // Skip this test in short mode if testing.Short() { t.Skip("skipping end-to-end test in short mode") } // Create test config arbCfg := &config.ArbitrumConfig{ RPCEndpoint: "https://arb1.arbitrum.io/rpc", ChainID: 42161, RateLimit: config.RateLimitConfig{ RequestsPerSecond: 10, MaxConcurrent: 5, Burst: 20, }, } botCfg := &config.BotConfig{ Enabled: true, PollingInterval: 1, MinProfitThreshold: 10.0, GasPriceMultiplier: 1.2, MaxWorkers: 2, // Use fewer workers for testing ChannelBufferSize: 5, RPCTimeout: 30, } uniswapCfg := &config.UniswapConfig{ FactoryAddress: "0x1F98431c8aD98523631AE4a59f267346ea31F984", PositionManagerAddress: "0xC36442b4a4522E871399CD717aBDD847Ab11FE88", FeeTiers: []int64{500, 3000, 10000}, Cache: config.CacheConfig{ Enabled: true, Expiration: 300, MaxSize: 10000, }, } // Create test logger log := logger.New("info", "text", "") // Create rate limiter manager rateLimiter := ratelimit.NewLimiterManager(arbCfg) // Create market manager marketMgr := market.NewMarketManager(uniswapCfg, log) // Create market scanner scanner := scanner.NewMarketScanner(botCfg, log) // Create monitor (this would normally connect to a real RPC endpoint) // For testing, we'll just verify it can be created monitor, err := monitor.NewArbitrumMonitor( arbCfg, botCfg, log, rateLimiter, marketMgr, scanner, ) assert.NoError(t, err) assert.NotNil(t, monitor) // Test that we can process a block of transactions // Create test transactions transactions := make([]*types.Transaction, 0) // Create a transaction that interacts with a DEX to := common.HexToAddress("0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640") // Uniswap V3 pool tx := types.NewTransaction(0, to, big.NewInt(0), 0, big.NewInt(0), nil) transactions = append(transactions, tx) // Create pipeline pipeline := market.NewPipeline(botCfg, log, marketMgr, scanner) pipeline.AddDefaultStages() // Process transactions through the pipeline ctx := context.Background() blockNumber := uint64(12345) timestamp := uint64(time.Now().Unix()) err = pipeline.ProcessTransactions(ctx, transactions, blockNumber, timestamp) assert.NoError(t, err) } func TestConfigurationLoading(t *testing.T) { // This test would normally load a real config file // For now, we'll just test that the config package works cfg := &config.Config{ Arbitrum: config.ArbitrumConfig{ RPCEndpoint: "https://arb1.arbitrum.io/rpc", ChainID: 42161, }, Bot: config.BotConfig{ Enabled: true, }, Uniswap: config.UniswapConfig{ FactoryAddress: "0x1F98431c8aD98523631AE4a59f267346ea31F984", }, Log: config.LogConfig{ Level: "info", }, Database: config.DatabaseConfig{ File: "mev-bot.db", }, } // Verify the config was created correctly assert.Equal(t, "https://arb1.arbitrum.io/rpc", cfg.Arbitrum.RPCEndpoint) assert.Equal(t, int64(42161), cfg.Arbitrum.ChainID) assert.True(t, cfg.Bot.Enabled) assert.Equal(t, "0x1F98431c8aD98523631AE4a59f267346ea31F984", cfg.Uniswap.FactoryAddress) assert.Equal(t, "info", cfg.Log.Level) assert.Equal(t, "mev-bot.db", cfg.Database.File) }