22import asyncio
33from pathlib import Path
44from typing import Dict , Optional , Tuple , List
5+ import concurrent
56
67from blspy import PrependSignature , PrivateKey , PublicKey , Util
78
@@ -159,10 +160,12 @@ async def new_challenge(self, new_challenge: harvester_protocol.NewChallenge):
159160 f"Invalid challenge size { challenge_size } , 32 was expected"
160161 )
161162
162- async def lookup_challenge (
163- filename : Path , prover : DiskProver
164- ) -> List [harvester_protocol .ChallengeResponse ]:
165- all_responses : List [harvester_protocol .ChallengeResponse ] = []
163+ loop = asyncio .get_running_loop ()
164+ executor = concurrent .futures .ThreadPoolExecutor (max_workers = 50 )
165+
166+ def blocking_lookup (filename : Path , prover : DiskProver ) -> Optional [List ]:
167+ # Uses the DiskProver object to lookup qualities. This is a blocking call,
168+ # so it should be run in a threadpool.
166169 try :
167170 quality_strings = prover .get_qualities_for_challenge (
168171 new_challenge .challenge_hash
@@ -179,6 +182,16 @@ async def lookup_challenge(
179182 f"Retry-Error using prover object on { filename } . Giving up."
180183 )
181184 quality_strings = None
185+ return quality_strings
186+
187+ async def lookup_challenge (
188+ filename : Path , prover : DiskProver
189+ ) -> List [harvester_protocol .ChallengeResponse ]:
190+ # Exectures a DiskProverLookup in a threadpool, and returns responses
191+ all_responses : List [harvester_protocol .ChallengeResponse ] = []
192+ quality_strings = await loop .run_in_executor (
193+ executor , blocking_lookup , filename , prover
194+ )
182195 if quality_strings is not None :
183196 for index , quality_str in enumerate (quality_strings ):
184197 self .challenge_hashes [quality_str ] = (
@@ -205,6 +218,7 @@ async def lookup_challenge(
205218 Message ("challenge_response" , response ),
206219 Delivery .RESPOND ,
207220 )
221+ executor .shutdown (wait = False )
208222
209223 @api_request
210224 async def request_proof_of_space (
0 commit comments