Skip to content

Commit e3ba0e4

Browse files
authored
Merge pull request #17 from chainstacklabs/fix/solana-metrics-slot-dedup
Use slot from transaction confirmation response
2 parents 17b4878 + 4369c26 commit e3ba0e4

File tree

1 file changed

+8
-19
lines changed

1 file changed

+8
-19
lines changed

metrics/solana_landing_rate.py

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from solders.instruction import Instruction
1515
from solders.keypair import Keypair
1616
from solders.pubkey import Pubkey
17+
from solders.rpc.responses import GetSignatureStatusesResp
1718
from solders.transaction import Transaction
1819

1920
from common.metric_config import MetricConfig, MetricLabelKey, MetricLabels
@@ -72,7 +73,7 @@ async def _get_slot(self, client: AsyncClient) -> int:
7273

7374
async def _confirm_transaction(
7475
self, client: AsyncClient, signature: str, timeout: int
75-
) -> None:
76+
) -> GetSignatureStatusesResp:
7677
try:
7778
confirmation_task = asyncio.create_task(
7879
client.confirm_transaction(
@@ -81,7 +82,10 @@ async def _confirm_transaction(
8182
sleep_seconds=0.3,
8283
)
8384
)
84-
await asyncio.wait_for(confirmation_task, timeout=timeout)
85+
confirmation = await asyncio.wait_for(confirmation_task, timeout=timeout)
86+
if not confirmation or not confirmation.context:
87+
raise ValueError("Invalid confirmation response")
88+
return confirmation
8589
except asyncio.TimeoutError:
8690
raise ValueError(f"Transaction confirmation timeout after {timeout}s")
8791

@@ -114,15 +118,6 @@ async def _prepare_memo_transaction(self, client: AsyncClient) -> Transaction:
114118
blockhash.value.blockhash,
115119
)
116120

117-
async def _update_slot_diff(
118-
self, client: AsyncClient, signature: str, start_slot: int
119-
) -> None:
120-
status = await client.get_signature_statuses([signature])
121-
if not status or not status.value[0] or not status.value[0].slot:
122-
raise ValueError(f"Failed to get signature status: {status}")
123-
confirmed_slot = status.value[0].slot
124-
self._slot_diff = max(confirmed_slot - start_slot, 0)
125-
126121
async def _check_health(self, client: AsyncClient) -> None:
127122
"""Check node health via getHealth RPC."""
128123
try:
@@ -154,21 +149,15 @@ async def fetch_data(self) -> Optional[float]:
154149
if not signature_response or not signature_response.value:
155150
raise ValueError("Failed to send transaction")
156151

157-
await self._confirm_transaction(
152+
confirmation = await self._confirm_transaction(
158153
client,
159154
signature_response.value,
160155
self.config.timeout,
161156
)
162157

163158
response_time = time.monotonic() - start_time
164-
165-
await asyncio.sleep(1)
166-
await self._update_slot_diff(client, signature_response.value, start_slot)
159+
self._slot_diff = max(confirmation.context.slot - start_slot, 0)
167160
self.update_metric_value(self._slot_diff, "slot_latency")
168-
169-
# It doesn't make sense to measure response/confirmation time
170-
# since slots in Solana always take 400 ms each. The main
171-
# metric here is the slot latency/delay.
172161
return response_time
173162

174163
finally:

0 commit comments

Comments
 (0)