|
3 | 3 | import asyncio
|
4 | 4 | import logging
|
5 | 5 | import time
|
| 6 | +from collections.abc import Awaitable, Sequence |
6 | 7 | from pathlib import Path
|
7 | 8 | from typing import TYPE_CHECKING, ClassVar, Optional, cast
|
8 | 9 |
|
@@ -65,6 +66,47 @@ def _plot_passes_filter(self, plot_info: PlotInfo, challenge: harvester_protocol
|
65 | 66 | challenge.sp_hash,
|
66 | 67 | )
|
67 | 68 |
|
| 69 | + async def _handle_v1_responses( |
| 70 | + self, |
| 71 | + awaitables: Sequence[Awaitable[tuple[Path, list[harvester_protocol.NewProofOfSpace]]]], |
| 72 | + start_time: float, |
| 73 | + peer: WSChiaConnection, |
| 74 | + ) -> int: |
| 75 | + proofs_found = 0 |
| 76 | + for filename_sublist_awaitable in asyncio.as_completed(awaitables): |
| 77 | + filename, sublist = await filename_sublist_awaitable |
| 78 | + time_taken = time.monotonic() - start_time |
| 79 | + if time_taken > 8: |
| 80 | + self.harvester.log.warning( |
| 81 | + f"Looking up qualities on {filename} took: {time_taken}. This should be below 8 seconds" |
| 82 | + f" to minimize risk of losing rewards." |
| 83 | + ) |
| 84 | + for response in sublist: |
| 85 | + proofs_found += 1 |
| 86 | + msg = make_msg(ProtocolMessageTypes.new_proof_of_space, response) |
| 87 | + await peer.send_message(msg) |
| 88 | + return proofs_found |
| 89 | + |
| 90 | + async def _handle_v2_responses( |
| 91 | + self, v2_awaitables: Sequence[Awaitable[Optional[PartialProofsData]]], start_time: float, peer: WSChiaConnection |
| 92 | + ) -> int: |
| 93 | + partial_proofs_found = 0 |
| 94 | + for quality_awaitable in asyncio.as_completed(v2_awaitables): |
| 95 | + partial_proofs_data = await quality_awaitable |
| 96 | + if partial_proofs_data is None: |
| 97 | + continue |
| 98 | + time_taken = time.monotonic() - start_time |
| 99 | + if time_taken > 8: |
| 100 | + self.harvester.log.warning( |
| 101 | + f"Looking up partial proofs on {partial_proofs_data.plot_identifier}" |
| 102 | + f"took: {time_taken}. This should be below 8 seconds" |
| 103 | + f"to minimize risk of losing rewards." |
| 104 | + ) |
| 105 | + partial_proofs_found += len(partial_proofs_data.partial_proofs) |
| 106 | + msg = make_msg(ProtocolMessageTypes.partial_proofs, partial_proofs_data) |
| 107 | + await peer.send_message(msg) |
| 108 | + return partial_proofs_found |
| 109 | + |
68 | 110 | @metadata.request(peer_required=True)
|
69 | 111 | async def harvester_handshake(
|
70 | 112 | self, harvester_handshake: harvester_protocol.HarvesterHandshake, peer: WSChiaConnection
|
@@ -139,37 +181,36 @@ def blocking_lookup_v2_partial_proofs(filename: Path, plot_info: PlotInfo) -> Op
|
139 | 181 | break
|
140 | 182 |
|
141 | 183 | # Filter qualities that pass the required_iters check (same as V1 flow)
|
142 |
| - good_qualities = [] |
| 184 | + good_partial_proofs = [] |
143 | 185 | sp_interval_iters = calculate_sp_interval_iters(self.harvester.constants, sub_slot_iters)
|
144 | 186 |
|
145 | 187 | for partial_proof in partial_proofs:
|
146 | 188 | quality_str = quality_for_partial_proof(partial_proof, new_challenge.challenge_hash)
|
147 | 189 | required_iters: uint64 = calculate_iterations_quality(
|
148 | 190 | self.harvester.constants,
|
149 | 191 | quality_str,
|
150 |
| - plot_info.prover.get_size(), # TODO: todo_v2_plots update for V2 |
| 192 | + plot_info.prover.get_size(), |
151 | 193 | difficulty,
|
152 | 194 | new_challenge.sp_hash,
|
153 | 195 | sub_slot_iters,
|
154 | 196 | new_challenge.last_tx_height,
|
155 | 197 | )
|
156 | 198 |
|
157 | 199 | if required_iters < sp_interval_iters:
|
158 |
| - good_qualities.append(partial_proof) |
| 200 | + good_partial_proofs.append(partial_proof) |
159 | 201 |
|
160 |
| - if len(good_qualities) == 0: |
| 202 | + if len(good_partial_proofs) == 0: |
161 | 203 | return None
|
162 | 204 |
|
163 | 205 | size = plot_info.prover.get_size().size_v2
|
164 | 206 | assert size is not None
|
165 | 207 | return PartialProofsData(
|
166 | 208 | new_challenge.challenge_hash,
|
167 | 209 | new_challenge.sp_hash,
|
168 |
| - good_qualities[0].hex() + str(filename.resolve()), |
169 |
| - good_qualities, |
| 210 | + good_partial_proofs[0].hex() + str(filename.resolve()), |
| 211 | + good_partial_proofs, |
170 | 212 | new_challenge.signage_point_index,
|
171 | 213 | size,
|
172 |
| - difficulty, |
173 | 214 | plot_info.pool_public_key,
|
174 | 215 | plot_info.pool_contract_puzzle_hash,
|
175 | 216 | plot_info.plot_public_key,
|
@@ -354,30 +395,22 @@ async def lookup_challenge(
|
354 | 395 | total_proofs_found = 0
|
355 | 396 | total_v2_partial_proofs_found = 0
|
356 | 397 |
|
357 |
| - # Process V1 plot responses (existing flow) |
358 |
| - for filename_sublist_awaitable in asyncio.as_completed(awaitables): |
359 |
| - filename, sublist = await filename_sublist_awaitable |
360 |
| - time_taken = time.monotonic() - start |
361 |
| - if time_taken > 8: |
362 |
| - self.harvester.log.warning( |
363 |
| - f"Looking up qualities on {filename} took: {time_taken}. This should be below 8 seconds" |
364 |
| - f" to minimize risk of losing rewards." |
365 |
| - ) |
366 |
| - else: |
367 |
| - pass |
368 |
| - # self.harvester.log.info(f"Looking up qualities on {filename} took: {time_taken}") |
369 |
| - for response in sublist: |
370 |
| - total_proofs_found += 1 |
371 |
| - msg = make_msg(ProtocolMessageTypes.new_proof_of_space, response) |
372 |
| - await peer.send_message(msg) |
373 |
| - |
374 |
| - # Process V2 plot quality collections (new flow) |
375 |
| - for quality_awaitable in asyncio.as_completed(v2_awaitables): |
376 |
| - partial_proofs_data = await quality_awaitable |
377 |
| - if partial_proofs_data is not None: |
378 |
| - total_v2_partial_proofs_found += len(partial_proofs_data.partial_proofs) |
379 |
| - msg = make_msg(ProtocolMessageTypes.partial_proofs, partial_proofs_data) |
380 |
| - await peer.send_message(msg) |
| 398 | + # run both concurrently |
| 399 | + tasks = [] |
| 400 | + if awaitables: |
| 401 | + tasks.append(self._handle_v1_responses(awaitables, start, peer)) |
| 402 | + if v2_awaitables: |
| 403 | + tasks.append(self._handle_v2_responses(v2_awaitables, start, peer)) |
| 404 | + |
| 405 | + if tasks: |
| 406 | + results = await asyncio.gather(*tasks) |
| 407 | + if len(results) == 2: |
| 408 | + total_proofs_found, total_v2_partial_proofs_found = results |
| 409 | + elif len(results) == 1: |
| 410 | + if awaitables: |
| 411 | + total_proofs_found = results[0] |
| 412 | + else: |
| 413 | + total_v2_partial_proofs_found = results[0] |
381 | 414 |
|
382 | 415 | now = uint64(time.time())
|
383 | 416 |
|
|
0 commit comments