Skip to content

Commit

Permalink
Merge pull request #55 from derekpierre/child-sampling
Browse files Browse the repository at this point in the history
`/get_ursulas` should perform node sampling using `TACoChildApplication` instead of `TACoApplication`
  • Loading branch information
derekpierre authored Nov 17, 2023
2 parents 56e457f + 028931c commit bdacdcc
Show file tree
Hide file tree
Showing 9 changed files with 111 additions and 48 deletions.
4 changes: 2 additions & 2 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ name = "pypi"
python_version = "3"

[packages]
nucypher = {git = "https://github.com/nucypher/nucypher.git", ref = "v7.0.0-rc.8"}
nucypher = {git = "https://github.com/nucypher/nucypher.git", ref = "v7.0.0-rc.10"}
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.8", extras = ["dev"]} # needed for testerchain, and must be editable
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
pytest = "<7" # match with nucypher/nucypher
pytest-cov = "*"
pytest-mock = "*"
Expand Down
12 changes: 6 additions & 6 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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@598ad313762fa2a5c8653f5996e888e75d9370ed#egg=nucypher
git+https://github.com/nucypher/nucypher.git@c0d12e14e4526f3fb3549a1176d0b2a79923c5ca#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'
Expand Down Expand Up @@ -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.33.1
sentry-sdk==1.35.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'
Expand Down
31 changes: 12 additions & 19 deletions porter/cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,15 @@ def porter_cli():

@porter_cli.command()
@group_general_config
@option_domain(default=str(domains.DEFAULT_DOMAIN), validate=True, required=False)
@option_eth_endpoint(required=False)
@option_domain(default=str(domains.DEFAULT_DOMAIN), validate=True, required=True)
@option_eth_endpoint(required=True)
@click.option(
"--polygon-endpoint",
"polygon_endpoint",
help="Connection URL for Polygon chain",
type=click.STRING,
required=True,
)
@option_teacher_uri
@option_registry_filepath
@option_min_stake
Expand Down Expand Up @@ -62,6 +69,7 @@ def run(
general_config,
domain,
eth_endpoint,
polygon_endpoint,
teacher_uri,
registry_filepath,
min_stake,
Expand All @@ -73,23 +81,6 @@ def run(
"""Start Porter's Web controller."""
emitter = setup_emitter(general_config, banner=BANNER)

# HTTP/HTTPS
if not eth_endpoint:
raise click.BadOptionUsage(
option_name="--eth-endpoint",
message=click.style(
"--eth-endpoint is required for decentralized porter.", fg="red"
),
)
if not domain:
# should never happen - domain defaults to 'mainnet' if not specified
raise click.BadOptionUsage(
option_name="--domain",
message=click.style(
"--domain is required for decentralized porter.", "red"
),
)

domain = domains.get_domain(domain)
registry = get_registry(domain=domain, registry_filepath=registry_filepath)
teacher = None
Expand All @@ -107,10 +98,12 @@ def run(
registry=registry,
start_learning_now=eager,
eth_endpoint=eth_endpoint,
polygon_endpoint=polygon_endpoint,
)

emitter.message(f"TACo Domain: {str(PORTER.domain).capitalize()}", color="green")
emitter.message(f"ETH Endpoint URI: {eth_endpoint}", color="green")
emitter.message(f"Polygon Endpoint URI: {polygon_endpoint}", color="green")

# firm up falsy status (i.e. change specified empty string to None)
allow_origins = allow_origins if allow_origins else None
Expand Down
45 changes: 31 additions & 14 deletions porter/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@
from eth_typing import ChecksumAddress
from eth_utils import to_checksum_address
from flask import Response, request
from nucypher.blockchain.eth.agents import ContractAgency, TACoApplicationAgent
from nucypher.blockchain.eth.domains import TACoDomain
from nucypher.blockchain.eth.agents import (
ContractAgency,
TACoChildApplicationAgent,
)
from nucypher.blockchain.eth.domains import DEFAULT_DOMAIN, TACoDomain
from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory
from nucypher.blockchain.eth.registry import ContractRegistry
from nucypher.characters.lawful import Ursula
Expand Down Expand Up @@ -84,31 +87,33 @@ class DecryptOutcome(NamedTuple):

def __init__(
self,
domain: TACoDomain = None,
eth_endpoint: str,
polygon_endpoint: str,
domain: TACoDomain = DEFAULT_DOMAIN,
registry: ContractRegistry = None,
controller: bool = True,
node_class: object = Ursula,
eth_endpoint: str = None,
execution_timeout: int = DEFAULT_EXECUTION_TIMEOUT,
*args,
**kwargs,
):
if not domain:
raise ValueError("TACo Domain must be provided.")
if not eth_endpoint:
raise ValueError('ETH Provider URI is required for decentralized Porter.')
raise ValueError("ETH Provider URI must be provided.")
if not polygon_endpoint:
raise ValueError("Polygon Provider URI must be provided.")

if not BlockchainInterfaceFactory.is_interface_initialized(
endpoint=eth_endpoint
):
BlockchainInterfaceFactory.initialize_interface(endpoint=eth_endpoint)
self._initialize_endpoints(eth_endpoint, polygon_endpoint)
self.eth_endpoint, self.polygon_endpoint = eth_endpoint, polygon_endpoint

self.eth_endpoint = eth_endpoint
self.registry = registry or ContractRegistry.from_latest_publication(
domain=domain
)
self.application_agent = ContractAgency.get_agent(
TACoApplicationAgent,
self.taco_child_application_agent = ContractAgency.get_agent(
TACoChildApplicationAgent,
registry=self.registry,
blockchain_endpoint=self.eth_endpoint,
blockchain_endpoint=self.polygon_endpoint,
)

super().__init__(save_metadata=True, domain=domain, node_class=node_class, *args, **kwargs)
Expand All @@ -125,6 +130,18 @@ def __init__(

self.log.info(BANNER)

@staticmethod
def _initialize_endpoints(eth_endpoint: str, polygon_endpoint: str):
if not BlockchainInterfaceFactory.is_interface_initialized(
endpoint=eth_endpoint
):
BlockchainInterfaceFactory.initialize_interface(endpoint=eth_endpoint)

if not BlockchainInterfaceFactory.is_interface_initialized(
endpoint=polygon_endpoint
):
BlockchainInterfaceFactory.initialize_interface(endpoint=polygon_endpoint)

def get_ursulas(self,
quantity: int,
exclude_ursulas: Optional[Sequence[ChecksumAddress]] = None,
Expand Down Expand Up @@ -224,7 +241,7 @@ def _make_reservoir(
include_ursulas: Optional[Sequence[ChecksumAddress]] = None,
):
return make_staking_provider_reservoir(
application_agent=self.application_agent,
application_agent=self.taco_child_application_agent,
exclude_addresses=exclude_ursulas,
include_addresses=include_ursulas,
)
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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@598ad313762fa2a5c8653f5996e888e75d9370ed#egg=nucypher
git+https://github.com/nucypher/nucypher.git@c0d12e14e4526f3fb3549a1176d0b2a79923c5ca#egg=nucypher
nucypher-core==0.13.0
packaging==23.2 ; python_version >= '3.7'
parsimonious==0.9.0
Expand Down
7 changes: 4 additions & 3 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
ContractAgency,
CoordinatorAgent,
StakingProvidersReservoir,
TACoApplicationAgent,
TACoChildApplicationAgent,
)
from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory
from nucypher.blockchain.eth.registry import ContractRegistry
Expand Down Expand Up @@ -182,7 +182,7 @@ def mock_reservoir(
}
return StakingProvidersReservoir(addresses)

mock_agent = mock_contract_agency.get_agent(TACoApplicationAgent)
mock_agent = mock_contract_agency.get_agent(TACoChildApplicationAgent)
mock_agent.get_staking_provider_reservoir = mock_reservoir


Expand All @@ -208,6 +208,7 @@ def porter(ursulas, mock_rest_middleware, test_registry):
porter = Porter(
domain=TEMPORARY_DOMAIN,
eth_endpoint=MOCK_ETH_PROVIDER_URI,
polygon_endpoint=MOCK_ETH_PROVIDER_URI,
registry=test_registry,
abort_on_learning_error=True,
start_learning_now=True,
Expand Down Expand Up @@ -340,7 +341,7 @@ def dkg_setup(
# Configure CoordinatorAgent
coordinator_agent.get_ritual.return_value = ritual
coordinator_agent.get_ritual_status.return_value = (
CoordinatorAgent.Ritual.Status.FINALIZED
CoordinatorAgent.Ritual.Status.ACTIVE
)
coordinator_agent.is_encryption_authorized.return_value = True

Expand Down
26 changes: 26 additions & 0 deletions tests/pre/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from typing import Iterable, Optional

import pytest
from eth_typing import ChecksumAddress
from nucypher.blockchain.eth.agents import (
StakingProvidersReservoir,
TACoApplicationAgent,
)


@pytest.fixture(scope="module", autouse=True)
def mock_sample_reservoir(testerchain, mock_contract_agency):
def mock_reservoir(
without: Optional[Iterable[ChecksumAddress]] = None, *args, **kwargs
):
addresses = {
address: 1
for address in testerchain.stake_providers_accounts
if address not in without
}
return StakingProvidersReservoir(addresses)

# TODO - this is needed for PRE Policy.enact(...) sample functionality which
# uses TACoApplication - should we change this (in `nucypher`)?
mock_agent = mock_contract_agency.get_agent(TACoApplicationAgent)
mock_agent.get_staking_provider_reservoir = mock_reservoir
28 changes: 27 additions & 1 deletion tests/test_porter_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ def test_porter_cli_run_simple(click_runner, teacher_uri):
TEMPORARY_DOMAIN_NAME,
"--eth-endpoint",
TEST_ETH_PROVIDER_URI,
"--polygon-endpoint",
TEST_ETH_PROVIDER_URI,
"--teacher",
teacher_uri,
)
Expand All @@ -42,6 +44,8 @@ def test_porter_cli_run_simple(click_runner, teacher_uri):
TEMPORARY_DOMAIN_NAME,
"--eth-endpoint",
TEST_ETH_PROVIDER_URI,
"--polygon-endpoint",
TEST_ETH_PROVIDER_URI,
"--http-port",
non_default_port,
"--teacher",
Expand All @@ -60,12 +64,30 @@ def test_porter_cli_run_eth_provider_must_be_provided(click_runner, teacher_uri)
"--dry-run",
"--domain",
TEMPORARY_DOMAIN_NAME,
"--polygon-endpoint",
TEST_ETH_PROVIDER_URI,
"--teacher",
teacher_uri,
)
result = click_runner.invoke(porter_cli, porter_run_command, catch_exceptions=False)
assert result.exit_code != 0, result.output
assert f"--eth-endpoint is required" in result.output
assert "Missing option '--eth-endpoint'" in result.output


def test_porter_cli_run_polygon_provider_must_be_provided(click_runner, teacher_uri):
porter_run_command = (
"run",
"--dry-run",
"--domain",
TEMPORARY_DOMAIN_NAME,
"--eth-endpoint",
TEST_ETH_PROVIDER_URI,
"--teacher",
teacher_uri,
)
result = click_runner.invoke(porter_cli, porter_run_command, catch_exceptions=False)
assert result.exit_code != 0, result.output
assert "Missing option '--polygon-endpoint'" in result.output


def test_cli_run_with_cors_origin(click_runner, teacher_uri):
Expand All @@ -78,6 +100,8 @@ def test_cli_run_with_cors_origin(click_runner, teacher_uri):
TEMPORARY_DOMAIN_NAME,
"--eth-endpoint",
TEST_ETH_PROVIDER_URI,
"--polygon-endpoint",
TEST_ETH_PROVIDER_URI,
"--teacher",
teacher_uri,
"--allow-origins",
Expand All @@ -99,6 +123,8 @@ def test_cli_run_with_empty_string_cors_origin(click_runner, teacher_uri):
TEMPORARY_DOMAIN_NAME,
"--eth-endpoint",
TEST_ETH_PROVIDER_URI,
"--polygon-endpoint",
TEST_ETH_PROVIDER_URI,
"--teacher",
teacher_uri,
"--allow-origins",
Expand Down

0 comments on commit bdacdcc

Please sign in to comment.