-
Notifications
You must be signed in to change notification settings - Fork 0
/
pow_calculator.py
49 lines (34 loc) · 1.41 KB
/
pow_calculator.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# coding: utf-8
from contextlib import contextmanager, suppress
import ctypes
from multiprocessing import cpu_count, Queue, Process
import queue
def calculate_pow(input_data, difficulty, timeout=7200):
'''Generate short random suffix for proof of work.
The concatenation of the input data and the suffix shall have a sha1 hash hex dump
with difficulty number of leading zeros.
The suffix shall contain utf-8 characters except newline, carriage return, tab and space.
'''
@contextmanager
def process_pool(result):
processes = [
Process(target=find_suffix_for_pow, args=(result, input_data, difficulty, random_seed))
for random_seed in range(cpu_count())
]
try:
for process in processes:
process.start()
yield
finally:
for process in processes:
process.terminate()
result = Queue(1)
with process_pool(result), suppress(queue.Empty):
return result.get(timeout=timeout)
raise TimeoutError
def find_suffix_for_pow(result, input_data, difficulty, random_seed):
dll = ctypes.cdll.LoadLibrary('./find_suffix_for_pow.so')
suffix = ctypes.create_string_buffer(b'', size=64)
dll.find_suffix_for_pow(suffix, len(suffix), input_data.encode(), difficulty, random_seed, cpu_count())
with suppress(queue.Full):
result.put_nowait(suffix.value.decode())