From 465e804d393303903415c9d1790d3747c4e3cc21 Mon Sep 17 00:00:00 2001 From: smypmsa Date: Fri, 25 Apr 2025 09:38:19 +0000 Subject: [PATCH] feat: add warming up endpoint, minor optimizations --- pyproject.toml | 1 + src/bot_runner.py | 4 ++++ src/core/client.py | 13 ++++++++++++- src/trading/buyer.py | 14 +++++++------- src/trading/trader.py | 18 ++++++++++++------ 5 files changed, 36 insertions(+), 14 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 8750aa5..30cbbed 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,6 +19,7 @@ dependencies = [ "grpcio-tools>=1.71.0", "protobuf>=5.29.4", "pyyaml>=6.0.2", + "uvloop>=0.21.0", ] [project.optional-dependencies] diff --git a/src/bot_runner.py b/src/bot_runner.py index 48a7f4a..35a53ae 100644 --- a/src/bot_runner.py +++ b/src/bot_runner.py @@ -4,6 +4,10 @@ import multiprocessing from datetime import datetime from pathlib import Path +import uvloop + +asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) + from config_loader import load_bot_config, print_config_summary from trading.trader import PumpTrader from utils.logger import setup_file_logging diff --git a/src/core/client.py b/src/core/client.py index 6d5fd16..786d4b6 100644 --- a/src/core/client.py +++ b/src/core/client.py @@ -80,6 +80,17 @@ class SolanaClient: await self._client.close() self._client = None + async def get_health(self) -> str | None: + body = { + "jsonrpc": "2.0", + "id": 1, + "method": "getHealth", + } + result = await self.post_rpc(body) + if result and "result" in result: + return result["result"] + return None + async def get_account_info(self, pubkey: Pubkey) -> dict[str, Any]: """Get account info from the blockchain. @@ -152,7 +163,7 @@ class SolanaClient: # Add priority fee instructions if applicable if priority_fee is not None: fee_instructions = [ - set_compute_unit_limit(75_000), # Default compute unit limit + set_compute_unit_limit(70_000), # Default compute unit limit set_compute_unit_price(priority_fee), ] instructions = fee_instructions + instructions diff --git a/src/trading/buyer.py b/src/trading/buyer.py index 9c565f8..7047d3f 100644 --- a/src/trading/buyer.py +++ b/src/trading/buyer.py @@ -92,13 +92,6 @@ class TokenBuyer(Trader): # Calculate maximum SOL to spend with slippage max_amount_lamports = int(amount_lamports * (1 + self.slippage)) - logger.info( - f"Buying {token_amount:.6f} tokens at {token_price_sol:.8f} SOL per token" - ) - logger.info( - f"Total cost: {self.amount:.6f} SOL (max: {max_amount_lamports / LAMPORTS_PER_SOL:.6f} SOL)" - ) - associated_token_account = self.wallet.get_associated_token_address( token_info.mint ) @@ -110,6 +103,13 @@ class TokenBuyer(Trader): max_amount_lamports, ) + logger.info( + f"Buying {token_amount:.6f} tokens at {token_price_sol:.8f} SOL per token" + ) + logger.info( + f"Total cost: {self.amount:.6f} SOL (max: {max_amount_lamports / LAMPORTS_PER_SOL:.6f} SOL)" + ) + success = await self.client.confirm_transaction(tx_signature) if success: diff --git a/src/trading/trader.py b/src/trading/trader.py index b69aa5f..8dcdd50 100644 --- a/src/trading/trader.py +++ b/src/trading/trader.py @@ -7,6 +7,7 @@ import asyncio import json import os from datetime import datetime +from time import monotonic from solders.pubkey import Pubkey @@ -204,6 +205,12 @@ class PumpTrader: logger.info(f"YOLO mode: {self.yolo_mode}") logger.info(f"Max token age: {self.max_token_age} seconds") + try: + health_resp = await self.solana_client.get_health() + logger.info(f"RPC warm-up successful (getHealth passed: {health_resp})") + except Exception as e: + logger.warning(f"RPC warm-up failed: {e!s}") + try: # Choose operating mode based on yolo_mode if not self.yolo_mode: @@ -261,7 +268,7 @@ class PumpTrader: # Only process if not already processed and fresh if token_key not in self.processed_tokens: # Record when the token was discovered - self.token_timestamps[token_key] = asyncio.get_event_loop().time() + self.token_timestamps[token_key] = monotonic() found_token = token self.processed_tokens.add(token_key) token_found.set() @@ -328,7 +335,7 @@ class PumpTrader: return # Record timestamp when token was discovered - self.token_timestamps[token_key] = asyncio.get_event_loop().time() + self.token_timestamps[token_key] = monotonic() await self.token_queue.put(token_info) logger.info(f"Queued new token: {token_info.symbol} ({token_info.mint})") @@ -341,7 +348,7 @@ class PumpTrader: token_key = str(token_info.mint) # Check if token is still "fresh" - current_time = asyncio.get_event_loop().time() + current_time = monotonic() token_age = current_time - self.token_timestamps.get( token_key, current_time ) @@ -378,11 +385,10 @@ class PumpTrader: token_info: Token information """ try: - # Save token info to file - await self._save_token_info(token_info) - # Wait for bonding curve to stabilize (unless in extreme fast mode) if not self.extreme_fast_mode: + # Save token info to file + # await self._save_token_info(token_info) logger.info( f"Waiting for {self.wait_time_after_creation} seconds for the bonding curve to stabilize..." )