Merge pull request #80 from chainstacklabs/feat/recent-blockhash-caching

Add recent blockhash caching
This commit is contained in:
Anton
2025-04-05 09:01:04 +00:00
committed by GitHub
+30 -2
View File
@@ -34,6 +34,27 @@ class SolanaClient:
"""
self.rpc_endpoint = rpc_endpoint
self._client = None
self._cached_blockhash: Hash | None = None
self._blockhash_lock = asyncio.Lock()
self._blockhash_updater_task = asyncio.create_task(self.start_blockhash_updater())
async def start_blockhash_updater(self, interval: float = 5.0):
"""Start background task to update recent blockhash."""
while True:
try:
blockhash = await self.get_latest_blockhash()
async with self._blockhash_lock:
self._cached_blockhash = blockhash
except Exception as e:
logger.warning(f"Blockhash fetch failed: {e!s}")
await asyncio.sleep(interval)
async def get_cached_blockhash(self) -> Hash:
"""Return the most recently cached blockhash."""
async with self._blockhash_lock:
if self._cached_blockhash is None:
raise RuntimeError("No cached blockhash available yet")
return self._cached_blockhash
async def get_client(self) -> AsyncClient:
"""Get or create the AsyncClient instance.
@@ -46,7 +67,14 @@ class SolanaClient:
return self._client
async def close(self):
"""Close the client connection if open."""
"""Close the client connection and stop the blockhash updater."""
if self._blockhash_updater_task:
self._blockhash_updater_task.cancel()
try:
await self._blockhash_updater_task
except asyncio.CancelledError:
pass
if self._client:
await self._client.close()
self._client = None
@@ -128,7 +156,7 @@ class SolanaClient:
]
instructions = fee_instructions + instructions
recent_blockhash = await self.get_latest_blockhash()
recent_blockhash = await self.get_cached_blockhash()
message = Message(instructions, signer_keypair.pubkey())
transaction = Transaction([signer_keypair], message, recent_blockhash)