From 856cc6818b80925a7f86e97c15937614b93b199f Mon Sep 17 00:00:00 2001 From: derekpierre Date: Fri, 10 Nov 2023 14:35:11 -0500 Subject: [PATCH 01/10] Allow a timeout to be specified as a parameter to Porter decrypt (web and python API). --- porter/interfaces.py | 2 ++ porter/main.py | 9 ++++++++- porter/schema.py | 15 +++++++++++++-- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/porter/interfaces.py b/porter/interfaces.py index 0dcdf23..04bc882 100644 --- a/porter/interfaces.py +++ b/porter/interfaces.py @@ -80,10 +80,12 @@ def decrypt( self, threshold: int, encrypted_decryption_requests: Dict[ChecksumAddress, bytes], + timeout: Optional[int] = None, ): decrypt_outcome = self.implementer.decrypt( threshold=threshold, encrypted_decryption_requests=encrypted_decryption_requests, + timeout=timeout, ) response_data = {"decryption_results": decrypt_outcome} return response_data diff --git a/porter/main.py b/porter/main.py index f2095a8..031ae28 100644 --- a/porter/main.py +++ b/porter/main.py @@ -224,11 +224,18 @@ def decrypt( encrypted_decryption_requests: Dict[ ChecksumAddress, EncryptedThresholdDecryptionRequest ], + timeout: Optional[int] = None, ) -> DecryptOutcome: decryption_client = ThresholdDecryptionClient(self) - successes, failures = decryption_client.gather_encrypted_decryption_shares( + + kwargs = dict( encrypted_requests=encrypted_decryption_requests, threshold=threshold ) + if timeout: + kwargs["timeout"] = timeout + successes, failures = decryption_client.gather_encrypted_decryption_shares( + **kwargs + ) decrypt_outcome = Porter.DecryptOutcome( encrypted_decryption_responses=successes, errors=failures diff --git a/porter/schema.py b/porter/schema.py index 838af47..dad67fc 100644 --- a/porter/schema.py +++ b/porter/schema.py @@ -3,7 +3,7 @@ from marshmallow import fields as marshmallow_fields from porter.cli.types import EIP55_CHECKSUM_ADDRESS -from porter.fields.base import JSON, Integer, PositiveInteger, StringList +from porter.fields.base import JSON, PositiveInteger, StringList from porter.fields.exceptions import InvalidArgumentCombo, InvalidInputData from porter.fields.retrieve import CapsuleFrag, RetrievalKit from porter.fields.taco import ( @@ -224,7 +224,7 @@ class Meta: class Decrypt(BaseSchema): - threshold = Integer( + threshold = PositiveInteger( required=True, load_only=True, click=click.option( @@ -245,6 +245,17 @@ class Decrypt(BaseSchema): "-e", help="Encrypted decryption requests dictionary keyed by ursula checksum address", type=click.STRING, + required=True, + ), + ) + timeout = PositiveInteger( + required=False, + load_only=True, + click=click.option( + "--timeout", + "-t", + help="Timeout for decryption operation", + type=click.INT, required=False, ), ) From b7e2624d76adae966d9a828c16c0dc29c56e4c7b Mon Sep 17 00:00:00 2001 From: derekpierre Date: Fri, 10 Nov 2023 14:36:42 -0500 Subject: [PATCH 02/10] Update TACo decrypt tests to include timeout. --- .../taco/test_porter_taco_python_interface.py | 27 +++- tests/taco/test_porter_taco_web_interface.py | 33 ++++- tests/taco/test_taco_specifications.py | 130 ++++++++++++------ 3 files changed, 146 insertions(+), 44 deletions(-) diff --git a/tests/taco/test_porter_taco_python_interface.py b/tests/taco/test_porter_taco_python_interface.py index 26b8554..0f5bcf9 100644 --- a/tests/taco/test_porter_taco_python_interface.py +++ b/tests/taco/test_porter_taco_python_interface.py @@ -1,3 +1,4 @@ +import pytest from nucypher_core import SessionStaticSecret, ThresholdDecryptionRequest from nucypher_core.ferveo import ( DecryptionShareSimple, @@ -6,7 +7,8 @@ ) -def test_taco_decryption(porter, dkg_setup, dkg_encrypted_data): +@pytest.mark.parametrize("timeout", [None, 5, 7, 9]) +def test_taco_decryption_success(porter, dkg_setup, dkg_encrypted_data, timeout): ritual_id, public_key, cohort, threshold = dkg_setup threshold_message_kit, expected_plaintext = dkg_encrypted_data @@ -37,7 +39,9 @@ def test_taco_decryption(porter, dkg_setup, dkg_encrypted_data): shared_secrets[ursula.checksum_address] = shared_secret decrypt_outcome = porter.decrypt( - threshold=threshold, encrypted_decryption_requests=encrypted_decryption_requests + threshold=threshold, + encrypted_decryption_requests=encrypted_decryption_requests, + timeout=timeout, ) # sufficient successes @@ -67,6 +71,21 @@ def test_taco_decryption(porter, dkg_setup, dkg_encrypted_data): cleartext = threshold_message_kit.decrypt_with_shared_secret(combined_shares) assert bytes(cleartext) == expected_plaintext + +@pytest.mark.parametrize("timeout", [None, 5, 7, 9]) +def test_taco_decryption_failure(porter, dkg_setup, dkg_encrypted_data, timeout): + ritual_id, public_key, cohort, threshold = dkg_setup + threshold_message_kit, expected_plaintext = dkg_encrypted_data + + decryption_request = ThresholdDecryptionRequest( + ritual_id=ritual_id, + variant=FerveoVariant.Simple, + ciphertext_header=threshold_message_kit.ciphertext_header, + acp=threshold_message_kit.acp, + ) + + requester_secret_key = SessionStaticSecret.random() + # # errors - invalid encrypting key used for request # @@ -82,7 +101,9 @@ def test_taco_decryption(porter, dkg_setup, dkg_encrypted_data): ) decrypt_outcome = porter.decrypt( - threshold=threshold, encrypted_decryption_requests=encrypted_decryption_requests + threshold=threshold, + encrypted_decryption_requests=encrypted_decryption_requests, + timeout=timeout, ) # sufficient successes diff --git a/tests/taco/test_porter_taco_web_interface.py b/tests/taco/test_porter_taco_web_interface.py index a319e1f..d124335 100644 --- a/tests/taco/test_porter_taco_web_interface.py +++ b/tests/taco/test_porter_taco_web_interface.py @@ -1,6 +1,7 @@ import json from base64 import b64decode +import pytest from eth_utils import to_checksum_address from nucypher_core import ( EncryptedThresholdDecryptionResponse, @@ -16,11 +17,16 @@ from porter.fields.taco import EncryptedThresholdDecryptionRequestField -def test_taco_decrypt(porter, porter_web_controller, dkg_setup, dkg_encrypted_data): +def test_taco_decrypt_bad_input(porter_web_controller): # Send bad data to assert error return response = porter_web_controller.post("/decrypt", data=json.dumps({"bad": "input"})) assert response.status_code == 400 + +@pytest.mark.parametrize("timeout", [None, 5, 7, 9]) +def test_taco_decrypt( + porter, porter_web_controller, dkg_setup, dkg_encrypted_data, timeout +): # Setup ritual_id, public_key, cohort, threshold = dkg_setup threshold_message_kit, expected_plaintext = dkg_encrypted_data @@ -59,6 +65,8 @@ def test_taco_decrypt(porter, porter_web_controller, dkg_setup, dkg_encrypted_da "threshold": threshold, "encrypted_decryption_requests": encrypted_decryption_requests, } + if timeout: + request_data["timeout"] = timeout # # Success @@ -106,6 +114,26 @@ def test_taco_decrypt(porter, porter_web_controller, dkg_setup, dkg_encrypted_da cleartext = threshold_message_kit.decrypt_with_shared_secret(combined_shares) assert bytes(cleartext) == expected_plaintext + +@pytest.mark.parametrize("timeout", [None, 5, 10, 15]) +def test_taco_decrypt_errors( + porter, porter_web_controller, dkg_setup, dkg_encrypted_data, timeout +): + # Setup + ritual_id, public_key, cohort, threshold = dkg_setup + threshold_message_kit, expected_plaintext = dkg_encrypted_data + + requester_secret_key = SessionStaticSecret.random() + + encrypted_request_field = EncryptedThresholdDecryptionRequestField() + + decryption_request = ThresholdDecryptionRequest( + ritual_id=ritual_id, + variant=FerveoVariant.Simple, + ciphertext_header=threshold_message_kit.ciphertext_header, + acp=threshold_message_kit.acp, + ) + # # Errors (some invalid threshold decryption requests) # @@ -143,6 +171,9 @@ def test_taco_decrypt(porter, porter_web_controller, dkg_setup, dkg_encrypted_da "threshold": threshold, "encrypted_decryption_requests": encrypted_decryption_requests, } + if timeout: + request_data["timeout"] = timeout + response = porter_web_controller.post("/decrypt", data=json.dumps(request_data)) response_data = json.loads(response.data) diff --git a/tests/taco/test_taco_specifications.py b/tests/taco/test_taco_specifications.py index f13d6ae..cdc160c 100644 --- a/tests/taco/test_taco_specifications.py +++ b/tests/taco/test_taco_specifications.py @@ -12,39 +12,24 @@ from porter.schema import Decrypt, DecryptOutcomeSchema -def test_taco_decrypt( - porter, dkg_setup, dkg_encrypted_data, get_random_checksum_address -): +def test_taco_decrypt_schema(dkg_setup, dkg_encrypted_data): ritual_id, public_key, cohort, threshold = dkg_setup threshold_message_kit, expected_plaintext = dkg_encrypted_data decrypt_schema = Decrypt() - decryption_request = ThresholdDecryptionRequest( - ritual_id=ritual_id, - variant=FerveoVariant.Simple, - ciphertext_header=threshold_message_kit.ciphertext_header, - acp=threshold_message_kit.acp, - context=None, - ) - requester_secret_key = SessionStaticSecret.random() + encrypted_decryption_requests = _generate_encrypted_requests( + cohort, requester_secret_key, ritual_id, threshold_message_kit + ) encrypted_request_field = EncryptedThresholdDecryptionRequestField() - encrypted_decryption_requests = {} - for ursula in cohort: - ursula_decryption_request_static_key = ( - ursula.threshold_request_power.get_pubkey_from_ritual_id(ritual_id) - ) - shared_secret = requester_secret_key.derive_shared_secret( - ursula_decryption_request_static_key - ) - encrypted_decryption_request = decryption_request.encrypt( - shared_secret=shared_secret, - requester_public_key=requester_secret_key.public_key(), - ) + for ( + checksum_address, + encrypted_decryption_request, + ) in encrypted_decryption_requests.items(): encrypted_decryption_requests[ - ursula.checksum_address + checksum_address ] = encrypted_request_field._serialize( value=encrypted_decryption_request, attr=None, obj=None ) @@ -87,6 +72,46 @@ def test_taco_decrypt( } decrypt_schema.load(request_data) + # invalid threshold value + with pytest.raises(InvalidInputData): + request_data = { + "threshold": 0, + "encrypted_decryption_requests": encrypted_decryption_requests, + } + decrypt_schema.load(request_data) + + with pytest.raises(InvalidInputData): + request_data = { + "threshold": -1, + "encrypted_decryption_requests": encrypted_decryption_requests, + } + decrypt_schema.load(request_data) + + # ivnalid timeout value + with pytest.raises(InvalidInputData): + request_data = { + "threshold": threshold, + "encrypted_decryption_requests": encrypted_decryption_requests, + "timeout": "some number", + } + decrypt_schema.load(request_data) + + with pytest.raises(InvalidInputData): + request_data = { + "threshold": threshold, + "encrypted_decryption_requests": encrypted_decryption_requests, + "timeout": 0, + } + decrypt_schema.load(request_data) + + with pytest.raises(InvalidInputData): + request_data = { + "threshold": threshold, + "encrypted_decryption_requests": encrypted_decryption_requests, + "timeout": -1, + } + decrypt_schema.load(request_data) + # invalid param combination with pytest.raises(InvalidArgumentCombo): request_data = { @@ -103,23 +128,18 @@ def test_taco_decrypt( } decrypt_schema.load(request_data) - # actual outcomes - encrypted_decryption_requests = {} - for ursula in cohort: - ursula_decryption_request_static_key = ( - ursula.threshold_request_power.get_pubkey_from_ritual_id(ritual_id) - ) - shared_secret = requester_secret_key.derive_shared_secret( - ursula_decryption_request_static_key - ) - encrypted_decryption_request = decryption_request.encrypt( - shared_secret=shared_secret, - requester_public_key=requester_secret_key.public_key(), - ) - encrypted_decryption_requests[ - ursula.checksum_address - ] = encrypted_decryption_request +def test_taco_decrypt(porter, dkg_setup, dkg_encrypted_data): + ritual_id, public_key, cohort, threshold = dkg_setup + threshold_message_kit, expected_plaintext = dkg_encrypted_data + + decrypt_schema = Decrypt() + + requester_secret_key = SessionStaticSecret.random() + + encrypted_decryption_requests = _generate_encrypted_requests( + cohort, requester_secret_key, ritual_id, threshold_message_kit + ) decrypt_outcome = porter.decrypt( threshold=threshold, encrypted_decryption_requests=encrypted_decryption_requests ) @@ -192,3 +212,33 @@ def test_taco_decrypt( ) assert output == {"decryption_results": faked_outcome_json} + + +def _generate_encrypted_requests( + cohort, requester_secret_key, ritual_id, threshold_message_kit +): + decryption_request = ThresholdDecryptionRequest( + ritual_id=ritual_id, + variant=FerveoVariant.Simple, + ciphertext_header=threshold_message_kit.ciphertext_header, + acp=threshold_message_kit.acp, + context=None, + ) + + encrypted_decryption_requests = {} + for ursula in cohort: + ursula_decryption_request_static_key = ( + ursula.threshold_request_power.get_pubkey_from_ritual_id(ritual_id) + ) + shared_secret = requester_secret_key.derive_shared_secret( + ursula_decryption_request_static_key + ) + encrypted_decryption_request = decryption_request.encrypt( + shared_secret=shared_secret, + requester_public_key=requester_secret_key.public_key(), + ) + encrypted_decryption_requests[ + ursula.checksum_address + ] = encrypted_decryption_request + + return encrypted_decryption_requests From 2d0c943a7850d2c9503fd160ac810a57ef874604 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 16 Nov 2023 17:08:30 -0500 Subject: [PATCH 03/10] Add max timeout for decryption operation. --- porter/main.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/porter/main.py b/porter/main.py index 031ae28..535cf7a 100644 --- a/porter/main.py +++ b/porter/main.py @@ -1,3 +1,4 @@ +import os from pathlib import Path from typing import Dict, List, NamedTuple, Optional, Sequence @@ -53,10 +54,10 @@ class Porter(Learner): _LONG_LEARNING_DELAY = 30 _ROUNDS_WITHOUT_NODES_AFTER_WHICH_TO_SLOW_DOWN = 25 - DEFAULT_EXECUTION_TIMEOUT = 15 # 15s - DEFAULT_PORT = 9155 + MAX_DECRYPTION_TIMEOUT = os.getenv("PORTER_MAX_DECRYPTION_TIMEOUT", default=15) # same default as `nucypher` + _interface_class = PorterInterface class UrsulaInfo(NamedTuple): @@ -232,7 +233,7 @@ def decrypt( encrypted_requests=encrypted_decryption_requests, threshold=threshold ) if timeout: - kwargs["timeout"] = timeout + kwargs["timeout"] = min(self.MAX_DECRYPTION_TIMEOUT, timeout) successes, failures = decryption_client.gather_encrypted_decryption_shares( **kwargs ) From 7fc275b24ae881f788e5755a24a7ce99bc8cec80 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 16 Nov 2023 19:43:55 -0500 Subject: [PATCH 04/10] Add timeout parameter for /get_ursulas endpoint - limited by a max value (default that can be modified via an environment variable). --- porter/interfaces.py | 12 ++++--- porter/main.py | 42 +++++++++++++--------- porter/schema.py | 12 +++++++ tests/conftest.py | 1 - tests/taco/test_taco_specifications.py | 2 +- tests/test_get_ursulas.py | 48 +++++++++++++++++++++++--- 6 files changed, 90 insertions(+), 27 deletions(-) diff --git a/porter/interfaces.py b/porter/interfaces.py index 04bc882..894b876 100644 --- a/porter/interfaces.py +++ b/porter/interfaces.py @@ -33,14 +33,18 @@ def __init__(self, porter: "main.Porter" = None, *args, **kwargs): super().__init__(implementer=porter, *args, **kwargs) @attach_schema(schema.GetUrsulas) - def get_ursulas(self, - quantity: int, - exclude_ursulas: Optional[List[ChecksumAddress]] = None, - include_ursulas: Optional[List[ChecksumAddress]] = None) -> Dict: + def get_ursulas( + self, + quantity: int, + exclude_ursulas: Optional[List[ChecksumAddress]] = None, + include_ursulas: Optional[List[ChecksumAddress]] = None, + timeout: Optional[int] = None, + ) -> Dict: ursulas_info = self.implementer.get_ursulas( quantity=quantity, exclude_ursulas=exclude_ursulas, include_ursulas=include_ursulas, + timeout=timeout, ) response_data = {"ursulas": ursulas_info} # list of UrsulaInfo objects diff --git a/porter/main.py b/porter/main.py index 535cf7a..fe5e6e9 100644 --- a/porter/main.py +++ b/porter/main.py @@ -56,7 +56,10 @@ class Porter(Learner): DEFAULT_PORT = 9155 - MAX_DECRYPTION_TIMEOUT = os.getenv("PORTER_MAX_DECRYPTION_TIMEOUT", default=15) # same default as `nucypher` + MAX_GET_URSULAS_TIMEOUT = os.getenv("PORTER_GET_URSULAS_TIMEOUT", default=15) + MAX_DECRYPTION_TIMEOUT = os.getenv( + "PORTER_MAX_DECRYPTION_TIMEOUT", default=15 + ) # TODO use same default constant as `nucypher` _interface_class = PorterInterface @@ -94,7 +97,6 @@ def __init__( registry: ContractRegistry = None, controller: bool = True, node_class: object = Ursula, - execution_timeout: int = DEFAULT_EXECUTION_TIMEOUT, *args, **kwargs, ): @@ -120,7 +122,6 @@ def __init__( super().__init__(save_metadata=True, domain=domain, node_class=node_class, *args, **kwargs) self.log = Logger(self.__class__.__name__) - self.execution_timeout = execution_timeout # Controller Interface self.interface = self._interface_class(porter=self) @@ -143,10 +144,18 @@ def _initialize_endpoints(eth_endpoint: str, polygon_endpoint: str): ): BlockchainInterfaceFactory.initialize_interface(endpoint=polygon_endpoint) - def get_ursulas(self, - quantity: int, - exclude_ursulas: Optional[Sequence[ChecksumAddress]] = None, - include_ursulas: Optional[Sequence[ChecksumAddress]] = None) -> List[UrsulaInfo]: + def get_ursulas( + self, + quantity: int, + exclude_ursulas: Optional[Sequence[ChecksumAddress]] = None, + include_ursulas: Optional[Sequence[ChecksumAddress]] = None, + timeout: Optional[int] = None, + ) -> List[UrsulaInfo]: + timeout = ( + min(timeout, self.MAX_GET_URSULAS_TIMEOUT) + if timeout + else self.MAX_GET_URSULAS_TIMEOUT + ) reservoir = self._make_reservoir(exclude_ursulas, include_ursulas) available_nodes_to_sample = len(reservoir.values) + len(reservoir.reservoir) if available_nodes_to_sample < quantity: @@ -172,16 +181,17 @@ def get_ursula_info(ursula_address) -> Porter.UrsulaInfo: self.log.debug(f"Ursula ({ursula_address}) is unreachable: {str(e)}") raise - self.block_until_number_of_known_nodes_is(quantity, - timeout=self.execution_timeout, - learn_on_this_thread=True, - eager=True) + self.block_until_number_of_known_nodes_is( + quantity, timeout=timeout, learn_on_this_thread=True, eager=True + ) - worker_pool = WorkerPool(worker=get_ursula_info, - value_factory=value_factory, - target_successes=quantity, - timeout=self.execution_timeout, - stagger_timeout=1) + worker_pool = WorkerPool( + worker=get_ursula_info, + value_factory=value_factory, + target_successes=quantity, + timeout=timeout, + stagger_timeout=1, + ) worker_pool.start() try: successes = worker_pool.block_until_target_successes() diff --git a/porter/schema.py b/porter/schema.py index dad67fc..55fe6b8 100644 --- a/porter/schema.py +++ b/porter/schema.py @@ -95,6 +95,18 @@ class GetUrsulas(BaseSchema): required=False, load_only=True) + timeout = PositiveInteger( + required=False, + load_only=True, + click=click.option( + "--timeout", + "-t", + help="Timeout for getting the required quantity of ursulas", + type=click.INT, + required=False, + ), + ) + # output ursulas = marshmallow_fields.List(marshmallow_fields.Nested(UrsulaInfoSchema), dump_only=True) diff --git a/tests/conftest.py b/tests/conftest.py index 7b5293b..0de3ac5 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -214,7 +214,6 @@ def porter(ursulas, mock_rest_middleware, test_registry): start_learning_now=True, known_nodes=ursulas, verify_node_bonding=False, - execution_timeout=2, network_middleware=mock_rest_middleware, ) yield porter diff --git a/tests/taco/test_taco_specifications.py b/tests/taco/test_taco_specifications.py index cdc160c..5162a9d 100644 --- a/tests/taco/test_taco_specifications.py +++ b/tests/taco/test_taco_specifications.py @@ -87,7 +87,7 @@ def test_taco_decrypt_schema(dkg_setup, dkg_encrypted_data): } decrypt_schema.load(request_data) - # ivnalid timeout value + # invalid timeout value with pytest.raises(InvalidInputData): request_data = { "threshold": threshold, diff --git a/tests/test_get_ursulas.py b/tests/test_get_ursulas.py index bcb50e6..c1db261 100644 --- a/tests/test_get_ursulas.py +++ b/tests/test_get_ursulas.py @@ -54,6 +54,13 @@ def test_get_ursulas_schema(get_random_checksum_address): updated_data["include_ursulas"] = include_ursulas GetUrsulas().load(updated_data) + # both exclude and include and timeout + updated_data = dict(required_data) + updated_data["exclude_ursulas"] = exclude_ursulas + updated_data["include_ursulas"] = include_ursulas + updated_data["timeout"] = 20 + GetUrsulas().load(updated_data) + # list input formatted as ',' separated strings updated_data = dict(required_data) updated_data["exclude_ursulas"] = ",".join(exclude_ursulas) @@ -118,6 +125,27 @@ def test_get_ursulas_schema(get_random_checksum_address): # 1 address in both include and exclude lists GetUrsulas().load(updated_data) + # invalid timeout value + with pytest.raises(InvalidInputData): + updated_data = dict(required_data) + updated_data["exclude_ursulas"] = exclude_ursulas + updated_data["timeout"] = "some number" + GetUrsulas().load(updated_data) + + with pytest.raises(InvalidInputData): + updated_data = dict(required_data) + updated_data["exclude_ursulas"] = exclude_ursulas + updated_data["include_ursulas"] = include_ursulas + updated_data["timeout"] = 0 + GetUrsulas().load(updated_data) + + with pytest.raises(InvalidInputData): + updated_data = dict(required_data) + updated_data["exclude_ursulas"] = exclude_ursulas + updated_data["include_ursulas"] = include_ursulas + updated_data["timeout"] = -1 + GetUrsulas().load(updated_data) + # # Output i.e. dump # @@ -139,7 +167,8 @@ def test_get_ursulas_schema(get_random_checksum_address): assert output == {"ursulas": expected_ursulas_info} -def test_get_ursulas_python_interface(porter, ursulas): +@pytest.mark.parametrize("timeout", [None, 15, 20]) +def test_get_ursulas_python_interface(porter, ursulas, timeout): # simple quantity = 4 ursulas_info = porter.get_ursulas(quantity=quantity) @@ -156,7 +185,7 @@ def test_get_ursulas_python_interface(porter, ursulas): ursulas_list[1].checksum_address, ] ursulas_info = porter.get_ursulas( - quantity=quantity, include_ursulas=include_ursulas + quantity=quantity, include_ursulas=include_ursulas, timeout=timeout ) returned_ursula_addresses = { ursula_info.checksum_address for ursula_info in ursulas_info @@ -171,7 +200,7 @@ def test_get_ursulas_python_interface(porter, ursulas): for i in range(number_to_exclude): exclude_ursulas.append(ursulas_list[i].checksum_address) ursulas_info = porter.get_ursulas( - quantity=quantity, exclude_ursulas=exclude_ursulas + quantity=quantity, exclude_ursulas=exclude_ursulas, timeout=timeout ) returned_ursula_addresses = { ursula_info.checksum_address for ursula_info in ursulas_info @@ -193,6 +222,7 @@ def test_get_ursulas_python_interface(porter, ursulas): quantity=quantity, include_ursulas=include_ursulas, exclude_ursulas=exclude_ursulas, + timeout=timeout, ) returned_ursula_addresses = { ursula_info.checksum_address for ursula_info in ursulas_info @@ -208,7 +238,8 @@ def test_get_ursulas_python_interface(porter, ursulas): porter.get_ursulas(quantity=len(ursulas) + 1) -def test_get_ursulas_web_interface(porter_web_controller, ursulas): +@pytest.mark.parametrize("timeout", [None, 10, 20]) +def test_get_ursulas_web_interface(porter_web_controller, ursulas, timeout): # Send bad data to assert error return response = porter_web_controller.get( "/get_ursulas", data=json.dumps({"bad": "input"}) @@ -232,6 +263,9 @@ def test_get_ursulas_web_interface(porter_web_controller, ursulas): "exclude_ursulas": exclude_ursulas, } + if timeout: + get_ursulas_params["timeout"] = timeout + # # Success # @@ -254,11 +288,15 @@ def test_get_ursulas_web_interface(porter_web_controller, ursulas): # # Test Query parameters # - response = porter_web_controller.get( + query_params = ( f"/get_ursulas?quantity={quantity}" f'&include_ursulas={",".join(include_ursulas)}' f'&exclude_ursulas={",".join(exclude_ursulas)}' ) + if timeout: + query_params += f"&timeout={timeout}" + + response = porter_web_controller.get(query_params) assert response.status_code == 200 response_data = json.loads(response.data) ursulas_info = response_data["result"]["ursulas"] From ce5af4e9eba2a7c6da9e26bccd837bfaf2dcdce0 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 16 Nov 2023 20:01:01 -0500 Subject: [PATCH 05/10] Log a warning whenever parameterized timeout exceeds maximum allowed timeout. Ensure that timeout for decryption is always passed to ThresholdDecryptionClient. --- porter/main.py | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/porter/main.py b/porter/main.py index fe5e6e9..0fdc3b5 100644 --- a/porter/main.py +++ b/porter/main.py @@ -151,11 +151,16 @@ def get_ursulas( include_ursulas: Optional[Sequence[ChecksumAddress]] = None, timeout: Optional[int] = None, ) -> List[UrsulaInfo]: - timeout = ( - min(timeout, self.MAX_GET_URSULAS_TIMEOUT) - if timeout - else self.MAX_GET_URSULAS_TIMEOUT - ) + if timeout and timeout > self.MAX_GET_URSULAS_TIMEOUT: + self.log.warn( + f"Provided sampling timeout ({timeout}s) exceeds " + f"maximum ({self.MAX_GET_URSULAS_TIMEOUT}s); " + f"using {self.MAX_GET_URSULAS_TIMEOUT}s instead" + ) + timeout = self.MAX_GET_URSULAS_TIMEOUT + else: + timeout = timeout or self.MAX_GET_URSULAS_TIMEOUT + reservoir = self._make_reservoir(exclude_ursulas, include_ursulas) available_nodes_to_sample = len(reservoir.values) + len(reservoir.reservoir) if available_nodes_to_sample < quantity: @@ -238,14 +243,20 @@ def decrypt( timeout: Optional[int] = None, ) -> DecryptOutcome: decryption_client = ThresholdDecryptionClient(self) + if timeout and timeout > self.MAX_DECRYPTION_TIMEOUT: + self.log.warn( + f"Provided decryption timeout ({timeout}s) exceeds " + f"maximum ({self.MAX_DECRYPTION_TIMEOUT}s); " + f"using {self.MAX_DECRYPTION_TIMEOUT}s instead" + ) + timeout = self.MAX_DECRYPTION_TIMEOUT + else: + timeout = timeout or self.MAX_DECRYPTION_TIMEOUT - kwargs = dict( - encrypted_requests=encrypted_decryption_requests, threshold=threshold - ) - if timeout: - kwargs["timeout"] = min(self.MAX_DECRYPTION_TIMEOUT, timeout) successes, failures = decryption_client.gather_encrypted_decryption_shares( - **kwargs + encrypted_requests=encrypted_decryption_requests, + threshold=threshold, + timeout=timeout, ) decrypt_outcome = Porter.DecryptOutcome( From ae1720c08d50c08f3c4549b1de823eb65120ce24 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Sat, 18 Nov 2023 18:44:44 -0500 Subject: [PATCH 06/10] Relock dependencies based on change in `nucypher`. --- Pipfile | 4 ++-- Pipfile.lock | 13 ++++++++----- dev-requirements.txt | 4 ++-- requirements.txt | 2 +- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/Pipfile b/Pipfile index c1b6378..723c475 100644 --- a/Pipfile +++ b/Pipfile @@ -7,13 +7,13 @@ name = "pypi" python_version = "3" [packages] -nucypher = {git = "https://github.com/nucypher/nucypher.git", ref = "v7.0.0-rc.10"} +nucypher = {git = "https://github.com/derekpierre/nucypher.git", ref = "node-timeouts"} nucypher-core = "==0.13.0" # must be the same as nucypher flask-cors = "*" prometheus-flask-exporter = "*" [dev-packages] -nucypher = {git = "https://github.com/nucypher/nucypher.git", editable = true, ref = "v7.0.0-rc.10", extras = ["dev"]} # needed for testerchain, and must be editable +nucypher = {git = "https://github.com/derekpierre/nucypher.git", editable = true, ref = "node-timeouts", extras = ["dev"]} # needed for testerchain, and must be editable pytest = "<7" # match with nucypher/nucypher pytest-cov = "*" pytest-mock = "*" diff --git a/Pipfile.lock b/Pipfile.lock index c563ed2..e4c7742 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "cb97453b370ef434cc8ac515b2e63564cf07c9b8b997e24f155f3ed25f5bbfb2" + "sha256": "921be080430cd3c8426997b002acb20e83bc40fe0680c7f2dfeb1ca35a211027" }, "pipfile-spec": 6, "requires": { @@ -1124,8 +1124,8 @@ "version": "==1.0.0" }, "nucypher": { - "git": "https://github.com/nucypher/nucypher.git", - "ref": "c0d12e14e4526f3fb3549a1176d0b2a79923c5ca" + "git": "https://github.com/derekpierre/nucypher.git", + "ref": "98e565c925f0eca0dda015e9cae98f8818e15c7b" }, "nucypher-core": { "hashes": [ @@ -2517,6 +2517,9 @@ "version": "==15.1.0" }, "coverage": { + "extras": [ + "toml" + ], "hashes": [ "sha256:027018943386e7b942fa832372ebc120155fd970837489896099f5cfa2890f79", "sha256:11b990d520ea75e7ee8dcab5bc908072aaada194a794db9f6d7d5cfd19661e5a", @@ -3638,8 +3641,8 @@ "version": "==1.8.0" }, "nucypher": { - "git": "https://github.com/nucypher/nucypher.git", - "ref": "c0d12e14e4526f3fb3549a1176d0b2a79923c5ca" + "git": "https://github.com/derekpierre/nucypher.git", + "ref": "98e565c925f0eca0dda015e9cae98f8818e15c7b" }, "nucypher-core": { "hashes": [ diff --git a/dev-requirements.txt b/dev-requirements.txt index 8a7eb14..d1c65a3 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -24,7 +24,7 @@ colorama==0.4.6 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3 commonmark==0.9.1 constant-sorrow==0.1.0a9 ; python_version >= '3' constantly==15.1.0 -coverage==6.5.0 +coverage[toml]==6.5.0 cryptography==41.0.5 ; python_version >= '3.7' cytoolz==0.12.2 ; python_version >= '3.6' dataclassy==0.11.1 ; python_version >= '3.6' @@ -83,7 +83,7 @@ msgspec==0.18.4 ; python_version >= '3.8' multidict==5.2.0 ; python_version >= '3.6' mypy-extensions==1.0.0 ; python_version >= '3.5' nodeenv==1.8.0 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6' -git+https://github.com/nucypher/nucypher.git@c0d12e14e4526f3fb3549a1176d0b2a79923c5ca#egg=nucypher +git+https://github.com/derekpierre/nucypher.git@98e565c925f0eca0dda015e9cae98f8818e15c7b#egg=nucypher nucypher-core==0.13.0 numpy==1.26.1 ; python_version < '3.13' and python_version >= '3.9' packaging==23.2 ; python_version >= '3.7' diff --git a/requirements.txt b/requirements.txt index b41e52e..ba8f781 100644 --- a/requirements.txt +++ b/requirements.txt @@ -53,7 +53,7 @@ msgpack==1.0.7 ; python_version >= '3.8' msgpack-python==0.5.6 multidict==5.2.0 ; python_version >= '3.6' mypy-extensions==1.0.0 ; python_version >= '3.5' -git+https://github.com/nucypher/nucypher.git@c0d12e14e4526f3fb3549a1176d0b2a79923c5ca#egg=nucypher +git+https://github.com/derekpierre/nucypher.git@98e565c925f0eca0dda015e9cae98f8818e15c7b#egg=nucypher nucypher-core==0.13.0 packaging==23.2 ; python_version >= '3.7' parsimonious==0.9.0 From 6335c3df8a7f27a357ae0c75c1354cea42318011 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Sat, 18 Nov 2023 18:45:17 -0500 Subject: [PATCH 07/10] Used default timeout for ThresholdDecryptionClient.DEFAULT_DECRYPTION_TIMEOUT so that it always matches the default timeout used in `nucypher`. --- porter/main.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/porter/main.py b/porter/main.py index 0fdc3b5..b06e0c5 100644 --- a/porter/main.py +++ b/porter/main.py @@ -58,8 +58,9 @@ class Porter(Learner): MAX_GET_URSULAS_TIMEOUT = os.getenv("PORTER_GET_URSULAS_TIMEOUT", default=15) MAX_DECRYPTION_TIMEOUT = os.getenv( - "PORTER_MAX_DECRYPTION_TIMEOUT", default=15 - ) # TODO use same default constant as `nucypher` + "PORTER_MAX_DECRYPTION_TIMEOUT", + default=ThresholdDecryptionClient.DEFAULT_DECRYPTION_TIMEOUT, + ) _interface_class = PorterInterface From b06e46c982fb78fd68712daf560d512766208238 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Fri, 1 Dec 2023 11:11:58 -0500 Subject: [PATCH 08/10] Update `nucypher` dependency to be `v7.0.0`. --- Pipfile | 4 ++-- Pipfile.lock | 31 ++++++++++++++----------------- dev-requirements.txt | 8 ++++---- requirements.txt | 4 ++-- 4 files changed, 22 insertions(+), 25 deletions(-) diff --git a/Pipfile b/Pipfile index 723c475..84a1f3f 100644 --- a/Pipfile +++ b/Pipfile @@ -7,13 +7,13 @@ name = "pypi" python_version = "3" [packages] -nucypher = {git = "https://github.com/derekpierre/nucypher.git", ref = "node-timeouts"} +nucypher = {git = "https://github.com/nucypher/nucypher.git", ref = "v7.0.0"} nucypher-core = "==0.13.0" # must be the same as nucypher flask-cors = "*" prometheus-flask-exporter = "*" [dev-packages] -nucypher = {git = "https://github.com/derekpierre/nucypher.git", editable = true, ref = "node-timeouts", extras = ["dev"]} # needed for testerchain, and must be editable +nucypher = {git = "https://github.com/nucypher/nucypher.git", editable = true, ref = "v7.0.0", extras = ["dev"]} # needed for testerchain, and must be editable pytest = "<7" # match with nucypher/nucypher pytest-cov = "*" pytest-mock = "*" diff --git a/Pipfile.lock b/Pipfile.lock index e4c7742..4700cce 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "921be080430cd3c8426997b002acb20e83bc40fe0680c7f2dfeb1ca35a211027" + "sha256": "44245636b42b4077da1acbb4f6bc0e651f83dbcd54475f7fd5991cf5a767916d" }, "pipfile-spec": 6, "requires": { @@ -1124,8 +1124,8 @@ "version": "==1.0.0" }, "nucypher": { - "git": "https://github.com/derekpierre/nucypher.git", - "ref": "98e565c925f0eca0dda015e9cae98f8818e15c7b" + "git": "https://github.com/nucypher/nucypher.git", + "ref": "c3d126f522cdf19e8badf76ed20af034897e2b4b" }, "nucypher-core": { "hashes": [ @@ -1254,11 +1254,11 @@ }, "prometheus-client": { "hashes": [ - "sha256:35f7a8c22139e2bb7ca5a698e92d38145bc8dc74c1c0bf56f25cca886a764e17", - "sha256:8de3ae2755f890826f4b6479e5571d4f74ac17a81345fe69a6778fdb92579184" + "sha256:4585b0d1223148c27a225b10dbec5ae9bc4c81a99a3fa80774fa6209935324e1", + "sha256:c88b1e6ecf6b41cd8fb5731c7ae919bf66df6ec6fafa555cd6c0e16ca169ae92" ], "markers": "python_version >= '3.8'", - "version": "==0.18.0" + "version": "==0.19.0" }, "prometheus-flask-exporter": { "hashes": [ @@ -2517,9 +2517,6 @@ "version": "==15.1.0" }, "coverage": { - "extras": [ - "toml" - ], "hashes": [ "sha256:027018943386e7b942fa832372ebc120155fd970837489896099f5cfa2890f79", "sha256:11b990d520ea75e7ee8dcab5bc908072aaada194a794db9f6d7d5cfd19661e5a", @@ -3641,8 +3638,8 @@ "version": "==1.8.0" }, "nucypher": { - "git": "https://github.com/derekpierre/nucypher.git", - "ref": "98e565c925f0eca0dda015e9cae98f8818e15c7b" + "git": "https://github.com/nucypher/nucypher.git", + "ref": "c3d126f522cdf19e8badf76ed20af034897e2b4b" }, "nucypher-core": { "hashes": [ @@ -3888,11 +3885,11 @@ }, "prometheus-client": { "hashes": [ - "sha256:35f7a8c22139e2bb7ca5a698e92d38145bc8dc74c1c0bf56f25cca886a764e17", - "sha256:8de3ae2755f890826f4b6479e5571d4f74ac17a81345fe69a6778fdb92579184" + "sha256:4585b0d1223148c27a225b10dbec5ae9bc4c81a99a3fa80774fa6209935324e1", + "sha256:c88b1e6ecf6b41cd8fb5731c7ae919bf66df6ec6fafa555cd6c0e16ca169ae92" ], "markers": "python_version >= '3.8'", - "version": "==0.18.0" + "version": "==0.19.0" }, "prompt-toolkit": { "hashes": [ @@ -4536,10 +4533,10 @@ }, "sentry-sdk": { "hashes": [ - "sha256:04e392db9a0d59bd49a51b9e3a92410ac5867556820465057c2ef89a38e953e9", - "sha256:a7865952701e46d38b41315c16c075367675c48d049b90a4cc2e41991ebc7efa" + "sha256:0017fa73b8ae2d4e57fd2522ee3df30453715b29d2692142793ec5d5f90b94a6", + "sha256:8feab81de6bbf64f53279b085bd3820e3e737403b0a0d9317f73a2c3374ae359" ], - "version": "==1.35.0" + "version": "==1.38.0" }, "service-identity": { "hashes": [ diff --git a/dev-requirements.txt b/dev-requirements.txt index d1c65a3..398dbd8 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -24,7 +24,7 @@ colorama==0.4.6 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3 commonmark==0.9.1 constant-sorrow==0.1.0a9 ; python_version >= '3' constantly==15.1.0 -coverage[toml]==6.5.0 +coverage==6.5.0 cryptography==41.0.5 ; python_version >= '3.7' cytoolz==0.12.2 ; python_version >= '3.6' dataclassy==0.11.1 ; python_version >= '3.6' @@ -83,7 +83,7 @@ msgspec==0.18.4 ; python_version >= '3.8' multidict==5.2.0 ; python_version >= '3.6' mypy-extensions==1.0.0 ; python_version >= '3.5' nodeenv==1.8.0 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6' -git+https://github.com/derekpierre/nucypher.git@98e565c925f0eca0dda015e9cae98f8818e15c7b#egg=nucypher +git+https://github.com/nucypher/nucypher.git@c3d126f522cdf19e8badf76ed20af034897e2b4b#egg=nucypher nucypher-core==0.13.0 numpy==1.26.1 ; python_version < '3.13' and python_version >= '3.9' packaging==23.2 ; python_version >= '3.7' @@ -96,7 +96,7 @@ pickleshare==0.7.5 platformdirs==3.11.0 ; python_version >= '3.7' pluggy==1.3.0 ; python_version >= '3.8' pre-commit==2.12.1 -prometheus-client==0.18.0 ; python_version >= '3.8' +prometheus-client==0.19.0 ; python_version >= '3.8' prompt-toolkit==3.0.39 ; python_full_version >= '3.7.0' protobuf==4.25.0rc2 ; python_version >= '3.8' ptyprocess==0.7.0 @@ -140,7 +140,7 @@ rlp==3.0.0 rpds-py==0.10.6 ; python_version >= '3.8' safe-pysha3==1.0.4 semantic-version==2.10.0 ; python_version >= '2.7' -sentry-sdk==1.35.0 +sentry-sdk==1.38.0 service-identity==23.1.0 ; python_version >= '3.8' setuptools==68.2.2 ; python_version >= '3.8' six==1.16.0 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2' diff --git a/requirements.txt b/requirements.txt index ba8f781..58fc6cb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -53,12 +53,12 @@ msgpack==1.0.7 ; python_version >= '3.8' msgpack-python==0.5.6 multidict==5.2.0 ; python_version >= '3.6' mypy-extensions==1.0.0 ; python_version >= '3.5' -git+https://github.com/derekpierre/nucypher.git@98e565c925f0eca0dda015e9cae98f8818e15c7b#egg=nucypher +git+https://github.com/nucypher/nucypher.git@c3d126f522cdf19e8badf76ed20af034897e2b4b#egg=nucypher nucypher-core==0.13.0 packaging==23.2 ; python_version >= '3.7' parsimonious==0.9.0 pendulum==3.0.0b1 ; python_version >= '3.8' -prometheus-client==0.18.0 ; python_version >= '3.8' +prometheus-client==0.19.0 ; python_version >= '3.8' prometheus-flask-exporter==0.23.0 protobuf==4.25.0rc2 ; python_version >= '3.8' py-ecc==6.0.0 ; python_version >= '3.6' and python_version < '4' From acdd731d27f8856c868967475a9ee87a30fb5764 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Fri, 1 Dec 2023 11:12:26 -0500 Subject: [PATCH 09/10] Update call to retrieve_cfrags to use context as dictionary instead of kwargs. --- porter/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/porter/main.py b/porter/main.py index b06e0c5..d0e5187 100644 --- a/porter/main.py +++ b/porter/main.py @@ -225,7 +225,7 @@ def retrieve_cfrags( alice_verifying_key, bob_encrypting_key, bob_verifying_key, - **context, + context, ) result_outcomes = [] for result, error in zip(results, errors): From f6086adb8fe5de7f207bb377a7d233ab03d68ad4 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Tue, 12 Dec 2023 11:28:43 -0500 Subject: [PATCH 10/10] Relock dependencies. --- Pipfile | 4 +- Pipfile.lock | 65 ++++------- dev-requirements.txt | 254 +++++++++++++++++++++---------------------- requirements.txt | 152 +++++++++++++------------- 4 files changed, 225 insertions(+), 250 deletions(-) diff --git a/Pipfile b/Pipfile index 84a1f3f..1c58fc6 100644 --- a/Pipfile +++ b/Pipfile @@ -7,13 +7,13 @@ name = "pypi" python_version = "3" [packages] -nucypher = {git = "https://github.com/nucypher/nucypher.git", ref = "v7.0.0"} +nucypher = {git = "https://github.com/nucypher/nucypher.git", ref = "v7.0.3"} nucypher-core = "==0.13.0" # must be the same as nucypher flask-cors = "*" prometheus-flask-exporter = "*" [dev-packages] -nucypher = {git = "https://github.com/nucypher/nucypher.git", editable = true, ref = "v7.0.0", extras = ["dev"]} # needed for testerchain, and must be editable +nucypher = {git = "https://github.com/nucypher/nucypher.git", editable = true, ref = "v7.0.3", extras = ["dev"]} # needed for testerchain, and must be editable pytest = "<7" # match with nucypher/nucypher pytest-cov = "*" pytest-mock = "*" diff --git a/Pipfile.lock b/Pipfile.lock index 4700cce..7c34022 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "44245636b42b4077da1acbb4f6bc0e651f83dbcd54475f7fd5991cf5a767916d" + "sha256": "e398b5eaea6dafa3790f13f3600966fed6b6c184781208606cef9b7e85e2092c" }, "pipfile-spec": 6, "requires": { @@ -533,7 +533,7 @@ "sha256:fa44215bc31675a6380cd896dadb7f2054a7b94cfb87e53e52af844c65406a54", "sha256:ff451d614ca1d4227db0ffa627fb51df71968cf0d9baf0210528dad10fdbc3ab" ], - "markers": "python_version >= '3.6'", + "markers": "implementation_name == 'cpython'", "version": "==0.12.2" }, "dateparser": { @@ -1125,7 +1125,8 @@ }, "nucypher": { "git": "https://github.com/nucypher/nucypher.git", - "ref": "c3d126f522cdf19e8badf76ed20af034897e2b4b" + "markers": "python_version >= '3'", + "ref": "4b029f707c021da8e87f5a753c9eadd86dbe4b30" }, "nucypher-core": { "hashes": [ @@ -1753,7 +1754,7 @@ "sha256:e9a9d150e098be3daee5c9f10859ab1bd14a61abebaed86e6d71f7f18c05b9d7", "sha256:f5fa9610f7e73fff42806a2ed8b06d862aa59ce4d178a52181771d6939c3e237" ], - "markers": "python_version >= '3.8'", + "markers": "implementation_name != 'pypy'", "version": "==2.13.0" }, "toolz": { @@ -2177,7 +2178,6 @@ "sha256:c923809f4f3542e86b18cbeb325b08800461b4af38366a8950d26afc15431e35", "sha256:ccd58558fad2a0003d1e0c026b8bfb5e35ec1600aa06ba2c2260daa5c64a2299" ], - "markers": "python_version >= '3.8' and python_version < '4'", "version": "==0.6.9" }, "appdirs": { @@ -2517,6 +2517,9 @@ "version": "==15.1.0" }, "coverage": { + "extras": [ + "toml" + ], "hashes": [ "sha256:027018943386e7b942fa832372ebc120155fd970837489896099f5cfa2890f79", "sha256:11b990d520ea75e7ee8dcab5bc908072aaada194a794db9f6d7d5cfd19661e5a", @@ -2570,6 +2573,7 @@ "sha256:fc2af30ed0d5ae0b1abdb4ebdce598eafd5b35397d4d75deb341a614d333d987" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==6.5.0" }, "cryptography": { @@ -2697,7 +2701,7 @@ "sha256:fa44215bc31675a6380cd896dadb7f2054a7b94cfb87e53e52af844c65406a54", "sha256:ff451d614ca1d4227db0ffa627fb51df71968cf0d9baf0210528dad10fdbc3ab" ], - "markers": "python_version >= '3.6'", + "markers": "implementation_name == 'cpython'", "version": "==0.12.2" }, "dataclassy": { @@ -2705,7 +2709,6 @@ "sha256:ad6622cb91e644d13f68768558983fbc22c90a8ff7e355638485d18b9baf1198", "sha256:bcb030d3d700cf9b1597042bbc8375b92773e6f68f65675a7071862c0ddb87f5" ], - "markers": "python_version >= '3.6'", "version": "==0.11.1" }, "dateparser": { @@ -2721,7 +2724,6 @@ "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330", "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186" ], - "markers": "python_version >= '3.5'", "version": "==5.1.1" }, "deprecated": { @@ -2729,7 +2731,6 @@ "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c", "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.2.14" }, "distlib": { @@ -2744,7 +2745,6 @@ "sha256:3997dace7e581b66a84d106a10baac47a3f6c94095d79c7d0971ca0ede1926ad", "sha256:c984c577358d1c7e5d4e52802bf4bd0432e965ba7326448998f95fcc1b6d5269" ], - "markers": "python_version >= '3.8' and python_version < '4'", "version": "==0.2.1" }, "eth-abi": { @@ -2768,7 +2768,6 @@ "sha256:78001209dfdf8c7973c649b8cbba73d3399cd649aeee4223d0b29078ae997201", "sha256:f6c5137a10edcc2a37a8f8736882e412b2fb3b326d00d8128538e73dc031f89b" ], - "markers": "python_version >= '3.8' and python_version < '4'", "version": "==0.6.19" }, "eth-bloom": { @@ -2841,7 +2840,6 @@ "sha256:1fcf4fd551133ec917b99406b206713f34112f5e3c030ece5dcb3e5ed8562ee3", "sha256:deaa9ec75cc8d02a047d5a2b065bd038ee6654ba2ffcf6e4c969181eacfdffc2" ], - "markers": "python_version >= '3.8' and python_version < '4'", "version": "==0.5.8" }, "evm-trace": { @@ -2849,7 +2847,6 @@ "sha256:0e5b6d6977bf42c3a5157ee3c5cdc5e57bd23827855283b516fa4e68d09e32e2", "sha256:5cd30ba28dcb2c7ba2461c124ad9059629c78bd0781f5c3f2a9939427f50cb47" ], - "markers": "python_version >= '3.8' and python_version < '4'", "version": "==0.1.0a25" }, "executing": { @@ -2864,7 +2861,6 @@ "sha256:08c21d87ded6e2b9da6728c3dff51baf1dcecf973b768ef35bcbc3447edb9ad4", "sha256:2e6f249f1f3654291606e046b09f1fd5eac39b360664c27f5aad072012f8bcbd" ], - "markers": "python_version >= '3.8'", "version": "==3.12.4" }, "flask": { @@ -3007,7 +3003,6 @@ "sha256:f351479a6914fd81a55c8e68963609f792d9b067fb8a60a042c585a621e0de4f", "sha256:f47932c434a3c8d3c86d865443fadc1fbf574e9b11d6650b656e602b1797908a" ], - "markers": "python_version >= '3.7'", "version": "==3.0.0" }, "hendrix": { @@ -3045,7 +3040,6 @@ "sha256:b45b8a651dfe4ce26f900ce6ccbce997d4fbec39ba03dd243516bf81fea8c0b8", "sha256:f4c2c004b9ec3e0e25332ad2cb6b91eba477a855557a7b5c6e79068809ff8b51" ], - "markers": "python_version >= '3.8'", "version": "==6.88.1" }, "identify": { @@ -3163,7 +3157,6 @@ "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb", "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743" ], - "markers": "python_version >= '3.8'", "version": "==6.8.0" }, "incremental": { @@ -3186,7 +3179,6 @@ "sha256:0852469d4d579d9cd613c220af7bf0c9cc251813e12be647cb9d463939db9b1e", "sha256:ad52f58fca8f9f848e256c629eff888efc0528c12fe0f8ec14f33205f23ef938" ], - "markers": "python_version >= '3.9'", "version": "==8.16.1" }, "itsdangerous": { @@ -3202,7 +3194,6 @@ "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd", "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0" ], - "markers": "python_version >= '3.6'", "version": "==0.19.1" }, "jinja2": { @@ -3409,7 +3400,6 @@ "sha256:f1f41aab5328aa5aaea9b16d083b128102f8712542f819fe7e6a420ff581b311", "sha256:f887e5f10ba98e8d2b150ddcf4702c1e5f8b3a20005eb0f74bfdbd360ee6f304" ], - "markers": "python_version >= '3.5'", "version": "==0.1.6" }, "maya": { @@ -3540,7 +3530,6 @@ "sha256:f6229dd49438d81ed7a3470e3cbc9646b1cc1b120d415a1786df880dabb1d1c4", "sha256:f668102958841c5bbd3ba7cf569a65d17aa3bdcf22124f394dfcfcf53cc5a9b9" ], - "markers": "python_version >= '3.8'", "version": "==0.18.4" }, "multidict": { @@ -3639,7 +3628,8 @@ }, "nucypher": { "git": "https://github.com/nucypher/nucypher.git", - "ref": "c3d126f522cdf19e8badf76ed20af034897e2b4b" + "markers": "python_version >= '3'", + "ref": "4b029f707c021da8e87f5a753c9eadd86dbe4b30" }, "nucypher-core": { "hashes": [ @@ -3698,7 +3688,6 @@ "sha256:e44ccb93f30c75dfc0c3aa3ce38f33486a75ec9abadabd4e59f114994a9c4617", "sha256:e509cbc488c735b43b5ffea175235cec24bbc57b227ef1acc691725beb230d1c" ], - "markers": "python_version < '3.13' and python_version >= '3.9'", "version": "==1.26.1" }, "packaging": { @@ -3739,7 +3728,6 @@ "sha256:e474390e60ed609cec869b0da796ad94f420bb057d86784191eefc62b65819ae", "sha256:f76d097d12c82a535fda9dfe5e8dd4127952b45fea9b0276cb30cca5ea313fbc" ], - "markers": "python_version >= '3.8'", "version": "==1.5.3" }, "parsimonious": { @@ -3753,7 +3741,6 @@ "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0", "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75" ], - "markers": "python_version >= '3.6'", "version": "==0.8.3" }, "pendulum": { @@ -3864,7 +3851,6 @@ "sha256:cf8ee52a3afdb965072dcc652433e0c7e3e40cf5ea1477cd4b3b1d2eb75495b3", "sha256:e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e" ], - "markers": "python_version >= '3.7'", "version": "==3.11.0" }, "pluggy": { @@ -3881,6 +3867,7 @@ "sha256:900d3c7e1bf4cf0374bb2893c24c23304952181405b4d88c9c40b72bda1bb8a9" ], "index": "pypi", + "markers": "python_full_version >= '3.6.1'", "version": "==2.12.1" }, "prometheus-client": { @@ -3896,7 +3883,6 @@ "sha256:04505ade687dc26dc4284b1ad19a83be2f2afe83e7a828ace0c72f3a1df72aac", "sha256:9dffbe1d8acf91e3de75f3b544e4842382fc06c6babe903ac9acb74dc6e08d88" ], - "markers": "python_full_version >= '3.7.0'", "version": "==3.0.39" }, "protobuf": { @@ -3965,7 +3951,6 @@ "sha256:1eb9c1d05b51133a6961889ec508cdcb19d24d32888704c4e034cae86a3accad", "sha256:f3563e2de8e78599cb9c69ee5bf3bded858ac6cf59891a04177f2353c425fdb7" ], - "markers": "python_version >= '3.7' and python_version < '4'", "version": "==3.13.0" }, "py-multibase": { @@ -3994,7 +3979,6 @@ "sha256:8f5caa4f54e227fc301e2e4c8aa868e869c2bc0c6636aa9e8115f8414bb891f9", "sha256:d8b0bd2b04f47cff6e92181739d9e94e41b2d62f056900761c797fa5babc76b6" ], - "markers": "python_version >= '3.6' and python_version < '4'", "version": "==1.1.1" }, "pyasn1": { @@ -4103,7 +4087,6 @@ "sha256:f59ef915cac80275245824e9d771ee939133be38215555e9dc90c6cb148aaeb5", "sha256:f8e81fc5fb17dae698f52bdd1c4f18b6ca674d7068242b2aff075f588301bbb0" ], - "markers": "python_version >= '3.7'", "version": "==1.10.13" }, "pyethash": { @@ -4117,7 +4100,6 @@ "sha256:3d87a822e6c868142f0c2c4bf16cce4696b5a7a4d142a7bd160e1bdf75bc54a9", "sha256:c44e3a121c15bf9d3a5cc98d94c9a047a5132a9b01d22264627f58ade9ddc217" ], - "markers": "python_version >= '3.7'", "version": "==1.59.1" }, "pygments": { @@ -4125,7 +4107,6 @@ "sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692", "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29" ], - "markers": "python_version >= '3.7'", "version": "==2.16.1" }, "pyjwt": { @@ -4136,7 +4117,6 @@ "sha256:57e28d156e3d5c10088e0c68abb90bfac3df82b40a71bd0daa20c65ccd5c23de", "sha256:59127c392cc44c2da5bb3192169a91f429924e17aff6534d70fdc02ab3e04320" ], - "markers": "python_version >= '3.7'", "version": "==2.8.0" }, "pynacl": { @@ -4169,6 +4149,7 @@ "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==6.2.5" }, "pytest-cov": { @@ -4177,6 +4158,7 @@ "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==4.1.0" }, "pytest-mock": { @@ -4185,6 +4167,7 @@ "sha256:31a40f038c22cad32287bb43932054451ff5583ff094bca6f675df2f8bc1a6e9" ], "index": "pypi", + "markers": "python_version >= '3.8'", "version": "==3.12.0" }, "pytest-timeout": { @@ -4192,7 +4175,6 @@ "sha256:3b0b95dabf3cb50bac9ef5ca912fa0cfc286526af17afc806824df20c2f72c90", "sha256:bde531e096466f49398a59f2dde76fa78429a09a12411466f88a07213e220de2" ], - "markers": "python_version >= '3.7'", "version": "==2.2.0" }, "pytest-twisted": { @@ -4200,7 +4182,6 @@ "sha256:1b63b73182bd1b995f30826a1d870c9ac0d08244ab0c871eb8bd0c8243acfb3d", "sha256:209bf5a6452cfbfb61de8f015902c14ec8126400911507074bb2ee4ce8dfe313" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==1.14.0" }, "python-baseconv": { @@ -4402,7 +4383,6 @@ "sha256:a4eb26484f2c82589bd9a17c73d32a010b1e29d89f1604cd9bf3a2097b81bb5e", "sha256:ba3a3775974105c221d31141f2c116f4fd65c5ceb0698657a11e9f295ec93fd0" ], - "markers": "python_full_version >= '3.6.3' and python_full_version < '4.0.0'", "version": "==12.6.0" }, "rlp": { @@ -4533,10 +4513,10 @@ }, "sentry-sdk": { "hashes": [ - "sha256:0017fa73b8ae2d4e57fd2522ee3df30453715b29d2692142793ec5d5f90b94a6", - "sha256:8feab81de6bbf64f53279b085bd3820e3e737403b0a0d9317f73a2c3374ae359" + "sha256:67f62238af273eebd6432f85116dc6cd5422d4bc02df886514e8139e755f48e4", + "sha256:9d3644b7c36a2c290f0d3275cba250202773f37545ef9097c8bcf561c6f5cdea" ], - "version": "==1.38.0" + "version": "==1.39.0" }, "service-identity": { "hashes": [ @@ -4627,7 +4607,6 @@ "sha256:f146c61ae128ab43ea3a0955de1af7e1633942c2b2b4985ac51cc292daf33222", "sha256:f776c2c30f0e5f4db45c3ee11a5f2a8d9de68e81eb73ec4237de1e32e04ae81c" ], - "markers": "python_version >= '3.7'", "version": "==2.0.22" }, "stack-data": { @@ -4704,7 +4683,7 @@ "sha256:e9a9d150e098be3daee5c9f10859ab1bd14a61abebaed86e6d71f7f18c05b9d7", "sha256:f5fa9610f7e73fff42806a2ed8b06d862aa59ce4d178a52181771d6939c3e237" ], - "markers": "python_version >= '3.8'", + "markers": "implementation_name != 'pypy'", "version": "==2.13.0" }, "toml": { @@ -4728,7 +4707,6 @@ "sha256:d302b3c5b53d47bce91fea46679d9c3c6508cf6332229aa1e7d8653723793386", "sha256:d88e651f9db8d8551a62556d3cff9e3034274ca5d66e93197cf2490e2dcb69c7" ], - "markers": "python_version >= '3.7'", "version": "==4.66.1" }, "traitlets": { @@ -4736,7 +4714,6 @@ "sha256:7564b5bf8d38c40fa45498072bf4dc5e8346eb087bbf1e2ae2d8774f6a0f078e", "sha256:98277f247f18b2c5cabaf4af369187754f4fb0e85911d473f72329db8a7f4fae" ], - "markers": "python_version >= '3.8'", "version": "==5.11.2" }, "trie": { @@ -5016,7 +4993,6 @@ "sha256:f9e10c3bf07074377fbbff3d2b02d740c17602ce5d6c91455977bdb32fbbebe8", "sha256:fc43eb869c6baba54dda3264109354a5d0ea621c51ba945ff71308347f24a1c9" ], - "markers": "python_version >= '3.6'", "version": "==1.16.0rc1" }, "yarl": { @@ -5104,7 +5080,6 @@ "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31", "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0" ], - "markers": "python_version >= '3.8'", "version": "==3.17.0" }, "zope-interface": { diff --git a/dev-requirements.txt b/dev-requirements.txt index 398dbd8..d7de2a6 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,174 +1,174 @@ -i https://pypi.python.org/simple -aiohttp==3.8.2 ; python_version >= '3.6' -aiosignal==1.3.1 ; python_version >= '3.7' -ape-solidity==0.6.9 ; python_version >= '3.8' and python_version < '4' +aiohttp==3.8.2; python_version >= '3.6' +aiosignal==1.3.1; python_version >= '3.7' +ape-solidity==0.6.9 appdirs==1.4.4 -appnope==0.1.3 ; sys_platform == 'darwin' +appnope==0.1.3; sys_platform == 'darwin' asttokens==2.4.0 -async-timeout==4.0.3 ; python_version >= '3.7' -attrs==23.1.0 ; python_version >= '3.7' -autobahn==23.6.2 ; python_version >= '3.9' +async-timeout==4.0.3; python_version >= '3.7' +attrs==23.1.0; python_version >= '3.7' +autobahn==23.6.2; python_version >= '3.9' automat==22.10.0 backcall==0.2.0 base58==1.0.3 bitarray==2.8.2 -blinker==1.6.3 ; python_version >= '3.7' +blinker==1.6.3; python_version >= '3.7' bytestring-splitter==2.4.1 cached-property==1.5.2 -certifi==2023.7.22 ; python_version >= '3.6' -cffi==1.16.0 ; python_version >= '3.8' -cfgv==3.4.0 ; python_version >= '3.8' -charset-normalizer==2.1.1 ; python_full_version >= '3.6.0' -click==8.1.7 ; python_version >= '3.7' -colorama==0.4.6 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6' +certifi==2023.7.22; python_version >= '3.6' +cffi==1.16.0; python_version >= '3.8' +cfgv==3.4.0; python_version >= '3.8' +charset-normalizer==2.1.1; python_full_version >= '3.6.0' +click==8.1.7; python_version >= '3.7' +colorama==0.4.6; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6' commonmark==0.9.1 -constant-sorrow==0.1.0a9 ; python_version >= '3' +constant-sorrow==0.1.0a9; python_version >= '3' constantly==15.1.0 -coverage==6.5.0 -cryptography==41.0.5 ; python_version >= '3.7' -cytoolz==0.12.2 ; python_version >= '3.6' -dataclassy==0.11.1 ; python_version >= '3.6' -dateparser==1.1.8 ; python_version >= '3.7' -decorator==5.1.1 ; python_version >= '3.5' -deprecated==1.2.14 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' +coverage[toml]==6.5.0; python_version >= '3.7' +cryptography==41.0.5; python_version >= '3.7' +cytoolz==0.12.2; implementation_name == 'cpython' +dataclassy==0.11.1 +dateparser==1.1.8; python_version >= '3.7' +decorator==5.1.1 +deprecated==1.2.14 distlib==0.3.7 -eip712==0.2.1 ; python_version >= '3.8' and python_version < '4' -eth-abi==4.2.1 ; python_full_version >= '3.7.2' and python_version < '4' -eth-account==0.8.0 ; python_version >= '3.6' and python_version < '4' -eth-ape==0.6.19 ; python_version >= '3.8' and python_version < '4' -eth-bloom==2.0.0 ; python_version >= '3.7' and python_version < '4' -eth-hash[pycryptodome]==0.5.2 ; python_version >= '3.7' and python_version < '4' +eip712==0.2.1 +eth-abi==4.2.1; python_version < '4' and python_full_version >= '3.7.2' +eth-account==0.8.0; python_version >= '3.6' and python_version < '4' +eth-ape==0.6.19 +eth-bloom==2.0.0; python_version >= '3.7' and python_version < '4' +eth-hash[pycryptodome]==0.5.2; python_version >= '3.7' and python_version < '4' eth-keyfile==0.6.1 eth-keys==0.4.0 -eth-rlp==0.3.0 ; python_version >= '3.7' and python_version < '4' -eth-tester==0.9.1b1 ; python_full_version >= '3.6.8' and python_version < '4' -eth-typing==3.5.1 ; python_full_version >= '3.7.2' and python_version < '4' -eth-utils==2.3.0 ; python_version >= '3.7' and python_version < '4' -ethpm-types==0.5.8 ; python_version >= '3.8' and python_version < '4' -evm-trace==0.1.0a25 ; python_version >= '3.8' and python_version < '4' +eth-rlp==0.3.0; python_version >= '3.7' and python_version < '4' +eth-tester==0.9.1b1; python_version < '4' and python_full_version >= '3.6.8' +eth-typing==3.5.1; python_version < '4' and python_full_version >= '3.7.2' +eth-utils==2.3.0; python_version >= '3.7' and python_version < '4' +ethpm-types==0.5.8 +evm-trace==0.1.0a25 executing==2.0.0 -filelock==3.12.4 ; python_version >= '3.8' -flask==3.0.0 ; python_version >= '3.8' -frozenlist==1.4.0 ; python_version >= '3.8' -greenlet==3.0.0 ; python_version >= '3.7' +filelock==3.12.4 +flask==3.0.0; python_version >= '3.8' +frozenlist==1.4.0; python_version >= '3.8' +greenlet==3.0.0 hendrix==4.0.0 -hexbytes==0.3.1 ; python_version >= '3.7' and python_version < '4' -humanize==4.8.0 ; python_version >= '3.8' +hexbytes==0.3.1; python_version >= '3.7' and python_version < '4' +humanize==4.8.0; python_version >= '3.8' hyperlink==21.0.0 -hypothesis==6.88.1 ; python_version >= '3.8' -identify==2.5.30 ; python_version >= '3.8' -idna==3.4 ; python_version >= '3.5' +hypothesis==6.88.1 +identify==2.5.30; python_version >= '3.8' +idna==3.4; python_version >= '3.5' ijson==3.2.3 -importlib-metadata==6.8.0 ; python_version >= '3.8' +importlib-metadata==6.8.0 incremental==22.10.0 -iniconfig==2.0.0 ; python_version >= '3.7' -ipython==8.16.1 ; python_version >= '3.9' -itsdangerous==2.1.2 ; python_version >= '3.7' -jedi==0.19.1 ; python_version >= '3.6' -jinja2==3.1.2 ; python_version >= '3.7' -jsonschema==4.19.1 ; python_version >= '3.8' -jsonschema-specifications==2023.7.1 ; python_version >= '3.8' +iniconfig==2.0.0; python_version >= '3.7' +ipython==8.16.1 +itsdangerous==2.1.2; python_version >= '3.7' +jedi==0.19.1 +jinja2==3.1.2; python_version >= '3.7' +jsonschema==4.19.1; python_version >= '3.8' +jsonschema-specifications==2023.7.1; python_version >= '3.8' lazyasd==0.1.4 lru-dict==1.2.0 -mako==1.2.4 ; python_version >= '3.7' -markupsafe==2.1.3 ; python_version >= '3.7' -marshmallow==3.20.1 ; python_version >= '3.8' -matplotlib-inline==0.1.6 ; python_version >= '3.5' +mako==1.2.4; python_version >= '3.7' +markupsafe==2.1.3; python_version >= '3.7' +marshmallow==3.20.1; python_version >= '3.8' +matplotlib-inline==0.1.6 maya==0.6.1 -mnemonic==0.20 ; python_version >= '3.5' +mnemonic==0.20; python_version >= '3.5' morphys==1.0 -msgpack==1.0.7 ; python_version >= '3.8' +msgpack==1.0.7; python_version >= '3.8' msgpack-python==0.5.6 -msgspec==0.18.4 ; python_version >= '3.8' -multidict==5.2.0 ; python_version >= '3.6' -mypy-extensions==1.0.0 ; python_version >= '3.5' -nodeenv==1.8.0 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6' -git+https://github.com/nucypher/nucypher.git@c3d126f522cdf19e8badf76ed20af034897e2b4b#egg=nucypher +msgspec==0.18.4 +multidict==5.2.0; python_version >= '3.6' +mypy-extensions==1.0.0; python_version >= '3.5' +nodeenv==1.8.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6' +nucypher@ git+https://github.com/nucypher/nucypher.git@4b029f707c021da8e87f5a753c9eadd86dbe4b30 nucypher-core==0.13.0 -numpy==1.26.1 ; python_version < '3.13' and python_version >= '3.9' -packaging==23.2 ; python_version >= '3.7' -pandas==1.5.3 ; python_version >= '3.8' +numpy==1.26.1 +packaging==23.2; python_version >= '3.7' +pandas==1.5.3 parsimonious==0.9.0 -parso==0.8.3 ; python_version >= '3.6' -pendulum==3.0.0b1 ; python_version >= '3.8' +parso==0.8.3 +pendulum==3.0.0b1; python_version >= '3.8' pexpect==4.8.0 pickleshare==0.7.5 -platformdirs==3.11.0 ; python_version >= '3.7' -pluggy==1.3.0 ; python_version >= '3.8' -pre-commit==2.12.1 -prometheus-client==0.19.0 ; python_version >= '3.8' -prompt-toolkit==3.0.39 ; python_full_version >= '3.7.0' -protobuf==4.25.0rc2 ; python_version >= '3.8' +platformdirs==3.11.0 +pluggy==1.3.0; python_version >= '3.8' +pre-commit==2.12.1; python_full_version >= '3.6.1' +prometheus-client==0.19.0; python_version >= '3.8' +prompt-toolkit==3.0.39 +protobuf==4.25.0rc2; python_version >= '3.8' ptyprocess==0.7.0 pure-eval==0.2.2 -py==1.11.0 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' +py==1.11.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' py-cid==0.3.0 -py-ecc==6.0.0 ; python_version >= '3.6' and python_version < '4' +py-ecc==6.0.0; python_version >= '3.6' and python_version < '4' py-evm==0.7.0a4 -py-geth==3.13.0 ; python_version >= '3.7' and python_version < '4' +py-geth==3.13.0 py-multibase==1.0.3 py-multicodec==0.2.1 py-multihash==0.2.3 -py-solc-x==1.1.1 ; python_version >= '3.6' and python_version < '4' -pyasn1==0.5.0 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5' -pyasn1-modules==0.3.0 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5' +py-solc-x==1.1.1 +pyasn1==0.5.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5' +pyasn1-modules==0.3.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5' pychalk==2.0.1 pycparser==2.21 -pycryptodome==3.19.0 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' -pydantic==1.10.13 ; python_version >= '3.7' +pycryptodome==3.19.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' +pydantic==1.10.13 pyethash==0.1.27 -pygithub==1.59.1 ; python_version >= '3.7' -pygments==2.16.1 ; python_version >= '3.7' -pyjwt[crypto]==2.8.0 ; python_version >= '3.7' -pynacl==1.5.0 ; python_version >= '3.6' -pyopenssl==23.2.0 ; python_version >= '3.6' -pytest==6.2.5 -pytest-cov==4.1.0 -pytest-mock==3.12.0 -pytest-timeout==2.2.0 ; python_version >= '3.7' -pytest-twisted==1.14.0 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' +pygithub==1.59.1 +pygments==2.16.1 +pyjwt[crypto]==2.8.0 +pynacl==1.5.0; python_version >= '3.6' +pyopenssl==23.2.0; python_version >= '3.6' +pytest==6.2.5; python_version >= '3.6' +pytest-cov==4.1.0; python_version >= '3.7' +pytest-mock==3.12.0; python_version >= '3.8' +pytest-timeout==2.2.0 +pytest-twisted==1.14.0 python-baseconv==1.2.2 -python-dateutil==2.8.2 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2' +python-dateutil==2.8.2; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' pytz==2023.3.post1 -pyunormalize==15.0.0 ; python_version >= '3.6' -pyyaml==6.0.1 ; python_version >= '3.6' -referencing==0.30.2 ; python_version >= '3.8' -regex==2023.10.3 ; python_version >= '3.7' -requests==2.31.0 ; python_version >= '3.7' -rich==12.6.0 ; python_full_version >= '3.6.3' and python_full_version < '4.0.0' +pyunormalize==15.0.0; python_version >= '3.6' +pyyaml==6.0.1; python_version >= '3.6' +referencing==0.30.2; python_version >= '3.8' +regex==2023.10.3; python_version >= '3.7' +requests==2.31.0; python_version >= '3.7' +rich==12.6.0 rlp==3.0.0 -rpds-py==0.10.6 ; python_version >= '3.8' +rpds-py==0.10.6; python_version >= '3.8' safe-pysha3==1.0.4 -semantic-version==2.10.0 ; python_version >= '2.7' -sentry-sdk==1.38.0 -service-identity==23.1.0 ; python_version >= '3.8' -setuptools==68.2.2 ; python_version >= '3.8' -six==1.16.0 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2' +semantic-version==2.10.0; python_version >= '2.7' +sentry-sdk==1.39.0 +service-identity==23.1.0; python_version >= '3.8' +setuptools==68.2.2; python_version >= '3.8' +six==1.16.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' snaptime==0.2.4 sortedcontainers==2.4.0 -sqlalchemy==2.0.22 ; python_version >= '3.7' +sqlalchemy==2.0.22 stack-data==0.6.3 -tabulate==0.9.0 ; python_version >= '3.7' -time-machine==2.13.0 ; python_version >= '3.8' -toml==0.10.2 ; python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2' -toolz==0.12.0 ; python_version >= '3.5' -tqdm==4.66.1 ; python_version >= '3.7' -traitlets==5.11.2 ; python_version >= '3.8' -trie==2.1.1 ; python_version >= '3.7' and python_version < '4' -twisted==23.8.0 ; python_full_version >= '3.7.1' -txaio==23.1.1 ; python_version >= '3.7' -typing-extensions==4.8.0 ; python_version >= '3.8' -tzdata==2023.3 ; python_version >= '2' -tzlocal==5.2 ; python_version >= '3.8' -urllib3==2.0.7 ; python_version >= '3.7' +tabulate==0.9.0; python_version >= '3.7' +time-machine==2.13.0; implementation_name != 'pypy' +toml==0.10.2; python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2' +toolz==0.12.0; python_version >= '3.5' +tqdm==4.66.1 +traitlets==5.11.2 +trie==2.1.1; python_version >= '3.7' and python_version < '4' +twisted==23.8.0; python_full_version >= '3.7.1' +txaio==23.1.1; python_version >= '3.7' +typing-extensions==4.8.0; python_version >= '3.8' +tzdata==2023.3; python_version >= '2' +tzlocal==5.2; python_version >= '3.8' +urllib3==2.0.7; python_version >= '3.7' varint==1.0.2 -virtualenv==20.24.6 ; python_version >= '3.7' -watchdog==3.0.0 ; python_version >= '3.7' +virtualenv==20.24.6; python_version >= '3.7' +watchdog==3.0.0; python_version >= '3.7' wcwidth==0.2.8 -web3==6.11.1 ; python_full_version >= '3.7.2' -websockets==12.0 ; python_version >= '3.8' -werkzeug==3.0.1 ; python_version >= '3.8' -wrapt==1.16.0rc1 ; python_version >= '3.6' -yarl==1.9.2 ; python_version >= '3.7' -zipp==3.17.0 ; python_version >= '3.8' -zope-interface==6.1 ; python_version >= '3.7' +web3==6.11.1; python_full_version >= '3.7.2' +websockets==12.0; python_version >= '3.8' +werkzeug==3.0.1; python_version >= '3.8' +wrapt==1.16.0rc1 +yarl==1.9.2; python_version >= '3.7' +zipp==3.17.0 +zope-interface==6.1; python_version >= '3.7' diff --git a/requirements.txt b/requirements.txt index 58fc6cb..e601874 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,103 +1,103 @@ -i https://pypi.python.org/simple -aiohttp==3.8.2 ; python_version >= '3.6' -aiosignal==1.3.1 ; python_version >= '3.7' +aiohttp==3.8.2; python_version >= '3.6' +aiosignal==1.3.1; python_version >= '3.7' appdirs==1.4.4 -async-timeout==4.0.3 ; python_version >= '3.7' -attrs==23.1.0 ; python_version >= '3.7' -autobahn==23.6.2 ; python_version >= '3.9' +async-timeout==4.0.3; python_version >= '3.7' +attrs==23.1.0; python_version >= '3.7' +autobahn==23.6.2; python_version >= '3.9' automat==22.10.0 bitarray==2.8.2 -blinker==1.6.3 ; python_version >= '3.7' +blinker==1.6.3; python_version >= '3.7' bytestring-splitter==2.4.1 cached-property==1.5.2 -certifi==2023.7.22 ; python_version >= '3.6' -cffi==1.16.0 ; python_version >= '3.8' -charset-normalizer==2.1.1 ; python_full_version >= '3.6.0' -click==8.1.7 ; python_version >= '3.7' -colorama==0.4.6 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6' -constant-sorrow==0.1.0a9 ; python_version >= '3' +certifi==2023.7.22; python_version >= '3.6' +cffi==1.16.0; python_version >= '3.8' +charset-normalizer==2.1.1; python_full_version >= '3.6.0' +click==8.1.7; python_version >= '3.7' +colorama==0.4.6; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6' +constant-sorrow==0.1.0a9; python_version >= '3' constantly==15.1.0 -cryptography==41.0.5 ; python_version >= '3.7' -cytoolz==0.12.2 ; python_version >= '3.6' -dateparser==1.1.8 ; python_version >= '3.7' -eth-abi==4.2.1 ; python_version < '4' and python_full_version >= '3.7.2' -eth-account==0.8.0 ; python_version >= '3.6' and python_version < '4' -eth-bloom==2.0.0 ; python_version >= '3.7' and python_version < '4' -eth-hash[pycryptodome]==0.5.2 ; python_version >= '3.7' and python_version < '4' +cryptography==41.0.5; python_version >= '3.7' +cytoolz==0.12.2; implementation_name == 'cpython' +dateparser==1.1.8; python_version >= '3.7' +eth-abi==4.2.1; python_version < '4' and python_full_version >= '3.7.2' +eth-account==0.8.0; python_version >= '3.6' and python_version < '4' +eth-bloom==2.0.0; python_version >= '3.7' and python_version < '4' +eth-hash[pycryptodome]==0.5.2; python_version >= '3.7' and python_version < '4' eth-keyfile==0.6.1 eth-keys==0.4.0 -eth-rlp==0.3.0 ; python_version >= '3.7' and python_version < '4' -eth-tester==0.9.1b1 ; python_version < '4' and python_full_version >= '3.6.8' -eth-typing==3.5.1 ; python_version < '4' and python_full_version >= '3.7.2' -eth-utils==2.3.0 ; python_version >= '3.7' and python_version < '4' -flask==3.0.0 ; python_version >= '3.8' +eth-rlp==0.3.0; python_version >= '3.7' and python_version < '4' +eth-tester==0.9.1b1; python_version < '4' and python_full_version >= '3.6.8' +eth-typing==3.5.1; python_version < '4' and python_full_version >= '3.7.2' +eth-utils==2.3.0; python_version >= '3.7' and python_version < '4' +flask==3.0.0; python_version >= '3.8' flask-cors==4.0.0 -frozenlist==1.4.0 ; python_version >= '3.8' +frozenlist==1.4.0; python_version >= '3.8' hendrix==4.0.0 -hexbytes==0.3.1 ; python_version >= '3.7' and python_version < '4' -humanize==4.8.0 ; python_version >= '3.8' +hexbytes==0.3.1; python_version >= '3.7' and python_version < '4' +humanize==4.8.0; python_version >= '3.8' hyperlink==21.0.0 -idna==3.4 ; python_version >= '3.5' +idna==3.4; python_version >= '3.5' incremental==22.10.0 -itsdangerous==2.1.2 ; python_version >= '3.7' -jinja2==3.1.2 ; python_version >= '3.7' -jsonschema==4.19.1 ; python_version >= '3.8' -jsonschema-specifications==2023.7.1 ; python_version >= '3.8' +itsdangerous==2.1.2; python_version >= '3.7' +jinja2==3.1.2; python_version >= '3.7' +jsonschema==4.19.1; python_version >= '3.8' +jsonschema-specifications==2023.7.1; python_version >= '3.8' lru-dict==1.2.0 -mako==1.2.4 ; python_version >= '3.7' -markupsafe==2.1.3 ; python_version >= '3.7' -marshmallow==3.20.1 ; python_version >= '3.8' +mako==1.2.4; python_version >= '3.7' +markupsafe==2.1.3; python_version >= '3.7' +marshmallow==3.20.1; python_version >= '3.8' maya==0.6.1 -mnemonic==0.20 ; python_version >= '3.5' -msgpack==1.0.7 ; python_version >= '3.8' +mnemonic==0.20; python_version >= '3.5' +msgpack==1.0.7; python_version >= '3.8' msgpack-python==0.5.6 -multidict==5.2.0 ; python_version >= '3.6' -mypy-extensions==1.0.0 ; python_version >= '3.5' -git+https://github.com/nucypher/nucypher.git@c3d126f522cdf19e8badf76ed20af034897e2b4b#egg=nucypher +multidict==5.2.0; python_version >= '3.6' +mypy-extensions==1.0.0; python_version >= '3.5' +nucypher@ git+https://github.com/nucypher/nucypher.git@4b029f707c021da8e87f5a753c9eadd86dbe4b30 nucypher-core==0.13.0 -packaging==23.2 ; python_version >= '3.7' +packaging==23.2; python_version >= '3.7' parsimonious==0.9.0 -pendulum==3.0.0b1 ; python_version >= '3.8' -prometheus-client==0.19.0 ; python_version >= '3.8' +pendulum==3.0.0b1; python_version >= '3.8' +prometheus-client==0.19.0; python_version >= '3.8' prometheus-flask-exporter==0.23.0 -protobuf==4.25.0rc2 ; python_version >= '3.8' -py-ecc==6.0.0 ; python_version >= '3.6' and python_version < '4' +protobuf==4.25.0rc2; python_version >= '3.8' +py-ecc==6.0.0; python_version >= '3.6' and python_version < '4' py-evm==0.7.0a4 -pyasn1==0.5.0 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5' -pyasn1-modules==0.3.0 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5' +pyasn1==0.5.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5' +pyasn1-modules==0.3.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5' pychalk==2.0.1 pycparser==2.21 -pycryptodome==3.19.0 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' +pycryptodome==3.19.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' pyethash==0.1.27 -pynacl==1.5.0 ; python_version >= '3.6' -pyopenssl==23.2.0 ; python_version >= '3.6' -python-dateutil==2.8.2 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' +pynacl==1.5.0; python_version >= '3.6' +pyopenssl==23.2.0; python_version >= '3.6' +python-dateutil==2.8.2; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' pytz==2023.3.post1 -pyunormalize==15.0.0 ; python_version >= '3.6' -referencing==0.30.2 ; python_version >= '3.8' -regex==2023.10.3 ; python_version >= '3.7' -requests==2.31.0 ; python_version >= '3.7' +pyunormalize==15.0.0; python_version >= '3.6' +referencing==0.30.2; python_version >= '3.8' +regex==2023.10.3; python_version >= '3.7' +requests==2.31.0; python_version >= '3.7' rlp==3.0.0 -rpds-py==0.10.6 ; python_version >= '3.8' -semantic-version==2.10.0 ; python_version >= '2.7' -service-identity==23.1.0 ; python_version >= '3.8' -setuptools==68.2.2 ; python_version >= '3.8' -six==1.16.0 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' +rpds-py==0.10.6; python_version >= '3.8' +semantic-version==2.10.0; python_version >= '2.7' +service-identity==23.1.0; python_version >= '3.8' +setuptools==68.2.2; python_version >= '3.8' +six==1.16.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' snaptime==0.2.4 sortedcontainers==2.4.0 -tabulate==0.9.0 ; python_version >= '3.7' -time-machine==2.13.0 ; python_version >= '3.8' -toolz==0.12.0 ; python_version >= '3.5' -trie==2.1.1 ; python_version >= '3.7' and python_version < '4' -twisted==23.8.0 ; python_full_version >= '3.7.1' -txaio==23.1.1 ; python_version >= '3.7' -typing-extensions==4.8.0 ; python_version >= '3.8' -tzdata==2023.3 ; python_version >= '2' -tzlocal==5.2 ; python_version >= '3.8' -urllib3==2.0.7 ; python_version >= '3.7' -watchdog==3.0.0 ; python_version >= '3.7' -web3==6.11.1 ; python_full_version >= '3.7.2' -websockets==12.0 ; python_version >= '3.8' -werkzeug==3.0.1 ; python_version >= '3.8' -yarl==1.9.2 ; python_version >= '3.7' -zope-interface==6.1 ; python_version >= '3.7' +tabulate==0.9.0; python_version >= '3.7' +time-machine==2.13.0; implementation_name != 'pypy' +toolz==0.12.0; python_version >= '3.5' +trie==2.1.1; python_version >= '3.7' and python_version < '4' +twisted==23.8.0; python_full_version >= '3.7.1' +txaio==23.1.1; python_version >= '3.7' +typing-extensions==4.8.0; python_version >= '3.8' +tzdata==2023.3; python_version >= '2' +tzlocal==5.2; python_version >= '3.8' +urllib3==2.0.7; python_version >= '3.7' +watchdog==3.0.0; python_version >= '3.7' +web3==6.11.1; python_full_version >= '3.7.2' +websockets==12.0; python_version >= '3.8' +werkzeug==3.0.1; python_version >= '3.8' +yarl==1.9.2; python_version >= '3.7' +zope-interface==6.1; python_version >= '3.7'