Skip to content

Commit

Permalink
frank/fast tx sender (#93)
Browse files Browse the repository at this point in the history
* wip fast tx sender

* feat: fast tx sender

* fix: lazy load blockhash subscription
  • Loading branch information
soundsonacid authored Jan 29, 2024
1 parent 3eae3de commit a2a408f
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 2 deletions.
45 changes: 45 additions & 0 deletions src/driftpy/tx/fast_tx_sender.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import asyncio

from solders.hash import Hash

from solana.rpc.async_api import AsyncClient
from solana.rpc.types import TxOpts
from solana.rpc.commitment import Commitment, Confirmed

from driftpy.tx.standard_tx_sender import StandardTxSender


class FastTxSender(StandardTxSender):
"""
The FastTxSender will refresh the latest blockhash in the background to save an RPC when building transactions.
"""

def __init__(
self,
connection: AsyncClient,
opts: TxOpts,
blockhash_refresh_interval_secs: int,
blockhash_commitment: Commitment = Confirmed,
):
super().__init__(connection, opts, blockhash_commitment)
self.blockhash_refresh_interval = blockhash_refresh_interval_secs
self.recent_blockhash = None

async def subscribe_blockhash(self):
"""
Must be called with asyncio.create_task to prevent blocking
"""
while True:
try:
blockhash_info = await self.connection.get_latest_blockhash(
self.blockhash_commitment
)
self.recent_blockhash = blockhash_info.value.blockhash
except Exception as e:
print(f"Error in subscribe_blockhash: {e}")
await asyncio.sleep(self.blockhash_refresh_interval)

async def fetch_latest_blockhash(self) -> Hash:
if self.recent_blockhash is None:
await self.subscribe_blockhash()
return self.recent_blockhash
7 changes: 5 additions & 2 deletions src/driftpy/tx/standard_tx_sender.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,16 @@ async def get_blockhash(self) -> Hash:
await self.connection.get_latest_blockhash(self.blockhash_commitment)
).value.blockhash

async def fetch_latest_blockhash(self) -> Hash:
return await self.get_blockhash()

async def get_legacy_tx(
self,
ixs: Sequence[Instruction],
payer: Keypair,
additional_signers: Optional[Sequence[Keypair]],
) -> Transaction:
latest_blockhash = await self.get_blockhash()
latest_blockhash = await self.fetch_latest_blockhash()
tx = Transaction(
instructions=ixs,
recent_blockhash=latest_blockhash,
Expand All @@ -60,7 +63,7 @@ async def get_versioned_tx(
lookup_tables: Sequence[AddressLookupTableAccount],
additional_signers: Optional[Sequence[Keypair]],
) -> VersionedTransaction:
latest_blockhash = await self.get_blockhash()
latest_blockhash = await self.fetch_latest_blockhash()
msg = MessageV0.try_compile(
payer.pubkey(), ixs, lookup_tables, latest_blockhash
)
Expand Down

0 comments on commit a2a408f

Please sign in to comment.