I am implementing a blockchain that communicates through http requests (inspired by this blogpost). This blockchain has a proof of work method, that, depending on the difficulty, can block other http requests for quite some time. This is why I am trying to implement the new asyncio
features from python. The following works:
async def proof_of_work(self, last_proof):
"""
Simple Proof of Work Algorithm:
- Find a number p' such that hash(pp') contains leading 4 zeroes, where p is the previous p'
"""
proof = 0
while self.valid_proof(last_proof, proof) is False:
proof += 1
await asyncio.sleep(1)
return proof
However, this makes my proof of work extremely slow, I guess this is because it is forced to sleep after each iteration. What would be a more elegant way to fix this?
while self.valid_proof(last_proof, proof) is False:
proof += 1
if proof % 1000 == 0:
await asyncio.sleep(1)
Would quicken it all up a bit, but it looks a bit dirty. What would be the correct way to implement this?
If you want to run CPU-blocking code inside coroutine, you should run it in separate execution flow (to avoid asyncio's event loop freezing) using
run_in_executor()
.You can use
ThreadPoolExecutor
if you just want another execution flow or (I think better) to useProcessPoolExecutor
to delegate CPU related work to other core(s).Output: