Zeth - Zerocash on Ethereum  0.8
Reference implementation of the Zeth protocol by Clearmatics
client.py
Go to the documentation of this file.
1 #!/usr/bin/env python3
2 
3 # Copyright (c) 2015-2022 Clearmatics Technologies Ltd
4 #
5 # SPDX-License-Identifier: LGPL-3.0+
6 
7 from .crypto import \
8  VerificationKey, Signature, export_digest, export_verification_key, \
9  export_signature
10 from .server_state import ServerState
11 from .contributor_list import ContributorList
12 from typing import Optional, Union
13 from requests import post, get, Response
14 from os.path import join, exists
15 import time
16 
17 CHUNK_SIZE = 4096
18 SERVER_BUSY_503_CLIENT_MSG = "Server is busy. Retrying ..."
19 
20 
21 class Client:
22 
23  def __init__(
24  self,
25  base_url: str,
26  cert_path: Optional[str] = None,
27  insecure: bool = False):
28  assert not cert_path or exists(cert_path)
29  self.base_url = base_url
30  self.verify: Union[bool, str, None] = False if insecure else cert_path
31 
32  def get_contributors(self) -> ContributorList:
33  """
34  GET /contributors
35  Get the status of the server.
36  """
37  while True:
38  resp = get(join(self.base_url, "contributors"), verify=self.verify)
39  if resp.status_code == 503:
40  print(SERVER_BUSY_503_CLIENT_MSG)
41  time.sleep(5.0)
42  continue
43 
44  resp.raise_for_status()
45  return ContributorList.from_json(resp.content.decode())
46 
47  def get_state(self) -> ServerState:
48  """
49  GET /state
50  Get the status of the server.
51  """
52  while True:
53  resp = get(join(self.base_url, "state"), verify=self.verify)
54  if resp.status_code == 503:
55  print(SERVER_BUSY_503_CLIENT_MSG)
56  time.sleep(5.0)
57  continue
58 
59  resp.raise_for_status()
60  return ServerState.from_json(resp.content.decode())
61 
62  def get_challenge(self, challenge_file: str) -> None:
63  """
64  GET /challenge request, downloading to file
65  """
66  # Contributors should be notified of their turn AFTER processing has
67  # completed on the previous contribution. However, it's possible for
68  # the next contributor, knowing his turn is next, to be waiting for
69  # processing to complete. Hence we loop with a message if the server
70  # claims to be temporarily unavailable.
71  def _get_challenge() -> Response:
72  return get(
73  join(self.base_url, "challenge"),
74  stream=True,
75  verify=self.verify)
76 
77  while True:
78  with _get_challenge() as resp:
79  if resp.status_code == 503:
80  print(SERVER_BUSY_503_CLIENT_MSG)
81  time.sleep(5.0)
82  continue
83 
84  resp.raise_for_status()
85  with open(challenge_file, "wb") as out_f:
86  for chunk in resp.iter_content(chunk_size=CHUNK_SIZE):
87  out_f.write(chunk)
88  break
89 
91  self,
92  response_file: str,
93  response_digest: bytes,
94  verification_key: VerificationKey,
95  signature: Signature) -> None:
96  """
97  POST /contribute, uploading from file with all authentication headers
98  """
99  headers = {
100  'X-MPC-Digest': export_digest(response_digest),
101  'X-MPC-Public-Key': export_verification_key(verification_key),
102  'X-MPC-Signature': export_signature(signature),
103  }
104  with open(response_file, "rb") as upload_f:
105  resp = post(
106  join(self.base_url, "contribute"),
107  files={'response': upload_f},
108  headers=headers,
109  verify=self.verify)
110  resp.raise_for_status()
coordinator.crypto.export_signature
str export_signature(bytes sig)
Definition: crypto.py:74
coordinator.crypto.export_verification_key
str export_verification_key(ecdsa.VerifyingKey vk)
Definition: crypto.py:66
coordinator.client.Client.get_contributors
ContributorList get_contributors(self)
Definition: client.py:32
coordinator.client.Client.push_contribution
None push_contribution(self, str response_file, bytes response_digest, VerificationKey verification_key, Signature signature)
Definition: client.py:90
coordinator.client.Client
Definition: client.py:21
coordinator.client.Client.get_challenge
None get_challenge(self, str challenge_file)
Definition: client.py:62
coordinator.client.Client.__init__
def __init__(self, str base_url, Optional[str] cert_path=None, bool insecure=False)
Definition: client.py:23
coordinator.crypto.export_digest
str export_digest(bytes digest)
Definition: crypto.py:32
coordinator.client.Client.base_url
base_url
Definition: client.py:25
coordinator.client.Client.get_state
ServerState get_state(self)
Definition: client.py:47