Skip to content

Commit

Permalink
done
Browse files Browse the repository at this point in the history
  • Loading branch information
odesenfans committed Sep 22, 2023
1 parent 5a8607e commit 212a664
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 33 deletions.
69 changes: 69 additions & 0 deletions mypy.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Global options:

[mypy]
mypy_path = src

exclude = conftest.py


show_column_numbers = True

# Suppressing errors
# Shows errors related to strict None checking, if the global strict_optional flag is enabled
strict_optional = True
no_implicit_optional = True

# Import discovery
# Suppresses error messages about imports that cannot be resolved
ignore_missing_imports = True
# Forces import to reference the original source file
no_implicit_reexport = True
# show error messages from unrelated files
follow_imports = silent
follow_imports_for_stubs = False


# Disallow dynamic typing
# Disallows usage of types that come from unfollowed imports
disallow_any_unimported = False
# Disallows all expressions in the module that have type Any
disallow_any_expr = False
# Disallows functions that have Any in their signature after decorator transformation.
disallow_any_decorated = False
# Disallows explicit Any in type positions such as type annotations and generic type parameters.
disallow_any_explicit = False
# Disallows usage of generic types that do not specify explicit type parameters.
disallow_any_generics = False
# Disallows subclassing a value of type Any.
disallow_subclassing_any = False

# Untyped definitions and calls
# Disallows calling functions without type annotations from functions with type annotations.
disallow_untyped_calls = False
# Disallows defining functions without type annotations or with incomplete type annotations
disallow_untyped_defs = False
# Disallows defining functions with incomplete type annotations.
check_untyped_defs = False
# Type-checks the interior of functions without type annotations.
disallow_incomplete_defs = False
# Reports an error whenever a function with type annotations is decorated with a decorator without annotations.
disallow_untyped_decorators = False

# Prohibit comparisons of non-overlapping types (ex: 42 == "no")
strict_equality = True

# Configuring warnings
# Warns about unneeded # type: ignore comments.
warn_unused_ignores = True
# Shows errors for missing return statements on some execution paths.
warn_no_return = True
# Shows a warning when returning a value with type Any from a function declared with a non- Any return type.
warn_return_any = False

# Miscellaneous strictness flags
# Allows variables to be redefined with an arbitrary type, as long as the redefinition is in the same block and nesting level as the original definition.
allow_redefinition = True

# Ignore the imported code from py-libp2p
[mypy-aleph.toolkit.libp2p_stubs.*]
ignore_errors = True
59 changes: 36 additions & 23 deletions src/aleph_vrf/coordinator/vrf.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
VRFRequest,
VRFResponse,
VRFResponseHash,
PublishedVRFResponseHash,
PublishedVRFRandomBytes,
)
from aleph_vrf.settings import settings
from aleph_vrf.utils import (
Expand Down Expand Up @@ -143,16 +145,16 @@ async def generate_vrf(account: ETHAccount) -> VRFResponse:
logger.debug(f"Generated VRF request with item_hash {request_item_hash}")

vrf_generated_result = await send_generate_requests(
selected_nodes, request_item_hash
selected_nodes=selected_nodes,
request_item_hash=request_item_hash,
request_id=vrf_request.request_id,
)

logger.debug(
f"Received VRF generated requests from {len(vrf_generated_result)} nodes"
)

vrf_publish_result = await send_publish_requests(
vrf_generated_result, vrf_request.request_id
)
vrf_publish_result = await send_publish_requests(vrf_generated_result)

logger.debug(
f"Received VRF publish requests from {len(vrf_generated_result)} nodes"
Expand All @@ -178,53 +180,64 @@ async def generate_vrf(account: ETHAccount) -> VRFResponse:


async def send_generate_requests(
selected_nodes: List[Node], request_item_hash: str
) -> Dict[str, Union[Exception, VRFResponseHash]]:
selected_nodes: List[Node],
request_item_hash: str,
request_id: str,
) -> Dict[str, PublishedVRFResponseHash]:
generate_tasks = []
nodes: List[str] = []
for node in selected_nodes:
nodes.append(node.address)
url = f"{node.address}/vm/{settings.FUNCTION}/{VRF_FUNCTION_GENERATE_PATH}/{request_item_hash}"
generate_tasks.append(asyncio.create_task(post_node_vrf(url, VRFResponseHash)))
generate_tasks.append(
asyncio.create_task(post_node_vrf(url, PublishedVRFResponseHash))
)

vrf_generated_responses = await asyncio.gather(
*generate_tasks, return_exceptions=True
)
return dict(zip(nodes, vrf_generated_responses))
generate_results = dict(zip(nodes, vrf_generated_responses))
for node, result in generate_results.items():
if isinstance(result, Exception):
raise ValueError(
f"Generate response not found for Node {node} on request_id {request_id}"
)

return generate_results


async def send_publish_requests(
vrf_generated_result: Dict[str, VRFResponseHash],
request_id: str,
) -> Dict[str, Union[Exception, VRFRandomBytes]]:
vrf_generated_result: Dict[str, PublishedVRFResponseHash],
) -> Dict[str, PublishedVRFRandomBytes]:
publish_tasks = []
nodes: List[str] = []

node_task_dict = {}

for node, vrf_generated_response in vrf_generated_result.items():
nodes.append(node)
if isinstance(vrf_generated_response, Exception):
raise ValueError(
f"Generate response not found for Node {node} on request_id {request_id}"
)

node_message_hash = vrf_generated_response.message_hash
url = (
f"{node}/vm/{settings.FUNCTION}"
f"/{VRF_FUNCTION_PUBLISH_PATH}/{node_message_hash}"
)
task = asyncio.create_task(post_node_vrf(url, VRFRandomBytes))
node_task_dict[node] = task
publish_tasks.append(
asyncio.create_task(post_node_vrf(url, PublishedVRFRandomBytes))
)

vrf_publish_responses = await asyncio.gather(*publish_tasks, return_exceptions=True)
publish_results = dict(zip(nodes, vrf_publish_responses))
for node, result in publish_results.items():
if isinstance(result, Exception):
raise ValueError(f"Publish response not found for {node}")

vrf_publish_responses = await asyncio.gather(*noef, return_exceptions=True)
return dict(zip(nodes, vrf_publish_responses))
return publish_results


def generate_final_vrf(
nb_executors: int,
nonce: int,
vrf_generated_result: Dict[str, Union[Exception, VRFResponseHash]],
vrf_publish_result: Dict[str, Union[Exception, VRFRandomBytes]],
vrf_generated_result: Dict[str, PublishedVRFResponseHash],
vrf_publish_result: Dict[str, PublishedVRFRandomBytes],
vrf_request: VRFRequest,
) -> VRFResponse:
nodes_responses = []
Expand Down
15 changes: 10 additions & 5 deletions src/aleph_vrf/executor/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
VRFResponseHash,
generate_request_from_message,
generate_response_hash_from_message,
PublishedVRFResponseHash,
PublishedVRFRandomBytes,
)
from aleph_vrf.utils import bytes_to_binary, bytes_to_int, generate

Expand Down Expand Up @@ -79,9 +81,11 @@ async def receive_generate(vrf_request: str) -> APIResponse:

message_hash = await publish_data(response_hash, ref, account)

response_hash.message_hash = message_hash
published_response_hash = PublishedVRFResponseHash.from_vrf_response_hash(
vrf_response_hash=response_hash, message_hash=message_hash
)

return APIResponse(data=response_hash)
return APIResponse(data=published_response_hash)


@app.post("/publish/{hash_message}")
Expand Down Expand Up @@ -114,10 +118,11 @@ async def receive_publish(hash_message: str) -> APIResponse:
ref = f"vrf_{response_hash.request_id}_{response_hash.execution_id}"

message_hash = await publish_data(response_bytes, ref, account)
published_random_bytes = PublishedVRFRandomBytes.from_vrf_random_bytes(
vrf_random_bytes=response_bytes, message_hash=message_hash
)

response_bytes.message_hash = message_hash

return APIResponse(data=response_bytes)
return APIResponse(data=published_random_bytes)


async def publish_data(
Expand Down
51 changes: 46 additions & 5 deletions src/aleph_vrf/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,43 @@ class VRFResponseHash(BaseModel):
execution_id: str
vrf_request: ItemHash
random_bytes_hash: str
message_hash: Optional[str] = None


def generate_response_hash_from_message(message: PostMessage) -> VRFResponseHash:
class PublishedVRFResponseHash(VRFResponseHash):
"""
A VRF response hash already published on aleph.im.
Includes the hash of the message published on aleph.im.
"""

message_hash: ItemHash

@classmethod
def from_vrf_response_hash(
cls, vrf_response_hash: VRFResponseHash, message_hash: ItemHash
) -> "PublishedVRFResponseHash":
return cls(
nb_bytes=vrf_response_hash.nb_bytes,
nonce=vrf_response_hash.nonce,
request_id=vrf_response_hash.request_id,
execution_id=vrf_response_hash.execution_id,
vrf_request=vrf_response_hash.request_id,
random_bytes_hash=vrf_response_hash.random_bytes_hash,
message_hash=message_hash,
)


def generate_response_hash_from_message(
message: PostMessage,
) -> PublishedVRFResponseHash:
content = message.content.content
return VRFResponseHash(
return PublishedVRFResponseHash(
nb_bytes=content["nb_bytes"],
nonce=content["nonce"],
request_id=content["request_id"],
execution_id=content["execution_id"],
vrf_request=ItemHash(content["vrf_request"]),
random_bytes_hash=content["random_bytes_hash"],
message_hash=content["message_hash"],
message_hash=message.item_hash,
)


Expand All @@ -69,7 +93,24 @@ class VRFRandomBytes(BaseModel):
random_bytes: str
random_bytes_hash: str
random_number: str
message_hash: Optional[str] = None


class PublishedVRFRandomBytes(VRFRandomBytes):
message_hash: ItemHash

@classmethod
def from_vrf_random_bytes(
cls, vrf_random_bytes: VRFRandomBytes, message_hash: ItemHash
) -> "PublishedVRFRandomBytes":
return cls(
request_id=vrf_random_bytes.request_id,
execution_id=vrf_random_bytes.execution_id,
vrf_request=vrf_random_bytes.request_id,
random_bytes=vrf_random_bytes.random_bytes,
random_bytes_hash=vrf_random_bytes.random_bytes_hash,
random_number=vrf_random_bytes.random_number,
message_hash=message_hash,
)


class CRNVRFResponse(BaseModel):
Expand Down

0 comments on commit 212a664

Please sign in to comment.