Merge pull request from derekpierre/network-entrenchment

TACo Domain Entrenchment/Assocation
pull/3275/head
LunarBytes 2023-10-06 11:54:30 +02:00 committed by GitHub
commit c93fc2884f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
99 changed files with 1403 additions and 1216 deletions
docs/source

View File

@ -178,9 +178,15 @@ man_pages = [
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(main_doc, 'NuCypher', 'NuCypher Documentation',
author, 'NuCypher', 'A proxy re-encryption network to empower privacy in decentralized systems.',
'Miscellaneous'),
(
main_doc,
"NuCypher",
"NuCypher Documentation",
author,
"NuCypher",
"A threshold access control application to empower privacy in decentralized systems.",
"Miscellaneous",
),
]

View File

@ -1,3 +1,4 @@
from nucypher.blockchain.eth.domains import TACoDomain
from nucypher.blockchain.eth.signers import InMemorySigner
from nucypher.characters.chaotic import NiceGuyEddie as _Enrico
from nucypher.characters.chaotic import ThisBobAlwaysDecrypts
@ -8,7 +9,7 @@ THIS_IS_NOT_A_TRINKET = 55 # sometimes called "public key"
signer = InMemorySigner()
enrico = _Enrico(encrypting_key=THIS_IS_NOT_A_TRINKET, signer=signer)
bob = ThisBobAlwaysDecrypts(domain="lynx", eth_provider_uri="Nowhere")
bob = ThisBobAlwaysDecrypts(domain=TACoDomain.LYNX.name, eth_endpoint="Nowhere")
ANYTHING_CAN_BE_PASSED_AS_RITUAL_ID = 55

View File

@ -20,8 +20,7 @@ and adding your provider and wallet details. To set the variables in your curre
Optionally, you can change the network the demo is running on by changing the value of `L1_NETWORK` and `L2_NETWORK`.
If you change these values be sure to also change `L1_PROVIDER_URI` and `L2_PROVIDER_URI` accordingly.
Available options for `L1_NETWORK` are `tapir` or `mainnet`.
Available options for `L2_NETWORK` are `mumbai` or `mainnet`
Available options for `TACO_NETWORK` are `lynx`, `tapir` or `mainnet`.
Ensure Alice's account has a bit of MATIC on polygon to pay for the policy.

View File

@ -5,6 +5,7 @@ from pathlib import Path
import maya
from nucypher.blockchain.eth.domains import TACoDomain
from nucypher.blockchain.eth.signers.base import Signer
from nucypher.characters.lawful import Alice, Bob
from nucypher.characters.lawful import Enrico as Enrico
@ -40,22 +41,21 @@ except KeyError:
print("\n************** Setup **************\n")
###########
# Network #
###########
##########
# Domain #
##########
L1_NETWORK = "lynx"
L2_NETWORK = "mumbai"
TACO_DOMAIN = TACoDomain.LYNX.name
#####################
# Bob the BUIDLer ##
#####################
# Then, there was bob. Bob learns about the
# rest of the network from the seednode.
# rest of the domain from the seednode.
bob = Bob(
domain=L1_NETWORK,
eth_provider_uri=L1_PROVIDER,
domain=TACO_DOMAIN,
eth_endpoint=L1_PROVIDER,
)
# Bob puts his public keys somewhere alice can find them.
@ -67,9 +67,9 @@ encrypting_key = bob.public_keys(DecryptingPower)
######################################
# Connect to the ethereum provider.
connect_web3_provider(eth_provider_uri=L1_PROVIDER)
connect_web3_provider(blockchain_endpoint=L1_PROVIDER)
# Connect to the layer 2 provider.
connect_web3_provider(eth_provider_uri=L2_PROVIDER)
connect_web3_provider(blockchain_endpoint=L2_PROVIDER)
# Setup and unlock alice's ethereum wallet.
# WARNING: Never give your mainnet password or mnemonic phrase to anyone.
@ -82,15 +82,16 @@ wallet.unlock_account(account=ALICE_ADDRESS, password=password)
# This is Alice's PRE payment method.
pre_payment_method = SubscriptionManagerPayment(
network=L2_NETWORK, eth_provider=L2_PROVIDER
domain=TACO_DOMAIN, blockchain_endpoint=L2_PROVIDER
)
# This is Alice.
alice = Alice(
checksum_address=ALICE_ADDRESS,
signer=wallet,
domain=L1_NETWORK,
eth_provider_uri=L1_PROVIDER,
domain=TACO_DOMAIN,
eth_endpoint=L1_PROVIDER,
polygon_endpoint=L2_PROVIDER,
pre_payment_method=pre_payment_method,
)
@ -111,7 +112,7 @@ policy_public_key = alice.get_policy_encrypting_key_from_label(label)
remote_bob = Bob.from_public_keys(
encrypting_key=encrypting_key,
verifying_key=verifying_key,
eth_provider_uri=L1_PROVIDER,
eth_endpoint=L1_PROVIDER,
)
# These are the policy details.

View File

@ -24,6 +24,7 @@ from pathlib import Path
import maya
from nucypher.blockchain.eth.domains import TACoDomain
from nucypher.blockchain.eth.signers import Signer
from nucypher.characters.lawful import Alice, Bob
from nucypher.policy.payment import SubscriptionManagerPayment
@ -57,16 +58,19 @@ try:
except KeyError:
raise RuntimeError("Missing environment variables to run demo.")
L1_NETWORK = "lynx"
L2_NETWORK = "mumbai"
TACO_DOMAIN = TACoDomain.LYNX.name
#######################################
# Alicia, the Authority of the Policy #
#######################################
connect_web3_provider(eth_provider_uri=L1_PROVIDER) # Connect to the ethereum provider.
connect_web3_provider(eth_provider_uri=L2_PROVIDER) # Connect to the layer 2 provider.
connect_web3_provider(
blockchain_endpoint=L1_PROVIDER
) # Connect to the ethereum provider.
connect_web3_provider(
blockchain_endpoint=L2_PROVIDER
) # Connect to the layer 2 provider.
# Setup and unlock alice's ethereum wallet.
@ -80,15 +84,16 @@ wallet.unlock_account(account=ALICE_ADDRESS, password=password)
# This is Alice's PRE payment method.
pre_payment_method = SubscriptionManagerPayment(
network=L2_NETWORK, eth_provider=L2_PROVIDER
domain=TACO_DOMAIN, blockchain_endpoint=L2_PROVIDER
)
# This is Alicia.
alicia = Alice(
checksum_address=ALICE_ADDRESS,
signer=wallet,
domain=L1_NETWORK,
eth_provider_uri=L1_PROVIDER,
domain=TACO_DOMAIN,
eth_endpoint=L1_PROVIDER,
polygon_endpoint=L2_PROVIDER,
pre_payment_method=pre_payment_method,
)

View File

@ -9,6 +9,7 @@ import msgpack
from nucypher_core import EncryptedTreasureMap, MessageKit
from nucypher_core.umbral import PublicKey
from nucypher.blockchain.eth.domains import TACoDomain
from nucypher.characters.lawful import Bob
from nucypher.crypto.keypairs import DecryptingKeypair, SigningKeypair
from nucypher.crypto.powers import DecryptingPower, SigningPower
@ -27,7 +28,7 @@ except KeyError:
raise RuntimeError("Missing environment variables to run demo.")
L1_NETWORK = "lynx"
TACO_DOMAIN = TACoDomain.LYNX.name
# To create a Bob, we need the doctor's private keys previously generated.
from doctor_keys import get_doctor_privkeys # noqa: E402
@ -43,9 +44,9 @@ power_ups = [enc_power, sig_power]
print("Creating the Doctor ...")
doctor = Bob(
domain=L1_NETWORK,
domain=TACO_DOMAIN,
crypto_power_ups=power_ups,
eth_provider_uri=L1_PROVIDER,
eth_endpoint=L1_PROVIDER,
)
print("Doctor = ", doctor)

View File

@ -47,8 +47,7 @@ and adding your provider and wallet details. To set the variables in your curre
Optionally, you can change the network the demo is running on by changing the value of `L1_NETWORK` and `L2_NETWORK`.
If you change these values be sure to also change `L1_PROVIDER_URI` and `L2_PROVIDER_URI` accordingly.
Available options for `L1_NETOWRK` are `tapir` or `mainnet`.
Available options for `L2_NETWORK` are `mumbai` or `polygon`
Available options for `TACO_NETWORK` are `lynx`, `tapir` or `mainnet`.
Ensure Alice's account has a bit of MATIC on polygon to pay for the policy.

View File

@ -3,6 +3,7 @@ import os
from nucypher_core.ferveo import DkgPublicKey
from nucypher.blockchain.eth.agents import CoordinatorAgent
from nucypher.blockchain.eth.domains import TACoDomain
from nucypher.blockchain.eth.registry import ContractRegistry
from nucypher.blockchain.eth.signers import InMemorySigner
from nucypher.characters.lawful import Bob, Enrico
@ -18,11 +19,10 @@ LOG_LEVEL = "info"
GlobalLoggerSettings.set_log_level(log_level_name=LOG_LEVEL)
GlobalLoggerSettings.start_console_logging()
staking_provider_uri = os.environ["DEMO_L1_PROVIDER_URI"]
network = "lynx"
eth_endpoint = os.environ["DEMO_L1_PROVIDER_URI"]
domain = TACoDomain.LYNX.name
coordinator_provider_uri = os.environ["DEMO_L2_PROVIDER_URI"]
coordinator_network = "mumbai"
polygon_endpoint = os.environ["DEMO_L2_PROVIDER_URI"]
###############
# Enrico
@ -30,9 +30,13 @@ coordinator_network = "mumbai"
print("--------- Threshold Encryption ---------")
registry = ContractRegistry.from_latest_publication(
domain=domain,
)
coordinator_agent = CoordinatorAgent(
provider_uri=coordinator_provider_uri,
registry=ContractRegistry.from_latest_publication(domain=coordinator_network),
blockchain_endpoint=polygon_endpoint,
registry=registry,
)
ritual_id = 1 # got this from a side channel
ritual = coordinator_agent.get_ritual(ritual_id)
@ -96,11 +100,10 @@ print(f"\nEncrypted message:\n{bytes(threshold_message_kit).hex()}")
print("--------- Threshold Decryption ---------")
bob = Bob(
eth_provider_uri=staking_provider_uri,
domain=network,
coordinator_provider_uri=coordinator_provider_uri,
coordinator_network=coordinator_network,
registry=ContractRegistry.from_latest_publication(domain=network),
domain=domain,
eth_endpoint=eth_endpoint,
polygon_endpoint=polygon_endpoint,
registry=registry,
)
bob.start_learning_loop(now=True)

View File

@ -3,6 +3,7 @@ import os
from nucypher_core.ferveo import DkgPublicKey
from nucypher.blockchain.eth.agents import CoordinatorAgent
from nucypher.blockchain.eth.domains import TACoDomain
from nucypher.blockchain.eth.registry import ContractRegistry
from nucypher.blockchain.eth.signers import InMemorySigner
from nucypher.characters.lawful import Bob, Enrico
@ -18,11 +19,10 @@ LOG_LEVEL = "info"
GlobalLoggerSettings.set_log_level(log_level_name=LOG_LEVEL)
GlobalLoggerSettings.start_console_logging()
staking_provider_uri = os.environ["DEMO_L1_PROVIDER_URI"]
network = "lynx"
eth_endpoint = os.environ["DEMO_L1_PROVIDER_URI"]
domain = TACoDomain.LYNX.name
coordinator_provider_uri = os.environ["DEMO_L2_PROVIDER_URI"]
coordinator_network = "mumbai"
polygon_endpoint = os.environ["DEMO_L2_PROVIDER_URI"]
###############
# Enrico
@ -30,9 +30,13 @@ coordinator_network = "mumbai"
print("--------- Threshold Encryption ---------")
registry = ContractRegistry.from_latest_publication(
domain=domain,
)
coordinator_agent = CoordinatorAgent(
provider_uri=coordinator_provider_uri,
registry=ContractRegistry.from_latest_publication(domain=coordinator_network),
blockchain_endpoint=polygon_endpoint,
registry=registry,
)
ritual_id = 1 # got this from a side channel
ritual = coordinator_agent.get_ritual(ritual_id)
@ -73,11 +77,10 @@ print(f"\nEncrypted message:\n{bytes(threshold_message_kit).hex()}")
print("--------- Threshold Decryption ---------")
bob = Bob(
eth_provider_uri=staking_provider_uri,
domain=network,
coordinator_provider_uri=coordinator_provider_uri,
coordinator_network=coordinator_network,
registry=ContractRegistry.from_latest_publication(domain=network),
domain=domain,
eth_endpoint=eth_endpoint,
polygon_endpoint=polygon_endpoint,
registry=registry,
)
bob.start_learning_loop(now=True)

View File

@ -0,0 +1,3 @@
Since the L2 network is always implied based on the TACo network connected to, we no longer need those config/parameters across the codebase, it can be inferred.
Each Character now takes optional eth and polygon endpoints.
Remove various usages of redundant L2 values. General rename from ``[eth_]provider[_uri]`` to ``[blockchain/eth/polygon]_endpoint``.

View File

@ -0,0 +1 @@
Deprecate configuration config/parameters ``pre-payment-network``, ``coordinator_uri`` since the L2 network is implied based on TACo network used.

View File

@ -14,7 +14,7 @@ __title__ = "nucypher"
__url__ = "https://github.com/nucypher/nucypher"
__summary__ = 'A proxy re-encryption network to empower privacy in decentralized systems.'
__summary__ = "A threshold access control application to empower privacy in decentralized systems."
__version__ = "6.2.0"

View File

@ -30,19 +30,18 @@ from nucypher.acumen.nicknames import Nickname
from nucypher.blockchain.eth.agents import (
ContractAgency,
CoordinatorAgent,
NucypherTokenAgent,
TACoApplicationAgent,
TACoChildApplicationAgent,
)
from nucypher.blockchain.eth.clients import PUBLIC_CHAINS
from nucypher.blockchain.eth.constants import NULL_ADDRESS
from nucypher.blockchain.eth.decorators import validate_checksum_address
from nucypher.blockchain.eth.domains import TACoDomain
from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory
from nucypher.blockchain.eth.registry import (
ContractRegistry,
)
from nucypher.blockchain.eth.signers import Signer
from nucypher.blockchain.eth.token import NU
from nucypher.blockchain.eth.trackers import dkg
from nucypher.blockchain.eth.trackers.bonding import OperatorBondedTracker
from nucypher.blockchain.eth.utils import truncate_checksum_address
@ -70,7 +69,7 @@ class BaseActor:
@validate_checksum_address
def __init__(
self,
domain: Optional[str],
domain: str,
registry: ContractRegistry,
transacting_power: Optional[TransactingPower] = None,
checksum_address: Optional[ChecksumAddress] = None,
@ -94,6 +93,7 @@ class BaseActor:
self.transacting_power = transacting_power
self.registry = registry
self.network = domain
self.taco_domain_info = TACoDomain.get_domain_info(self.network)
self._saved_receipts = list() # track receipts of transmitted transactions
def __repr__(self):
@ -130,24 +130,6 @@ class NucypherTokenActor(BaseActor):
super().__init__(registry=registry, **kwargs)
self.__token_agent = None
@property
def token_agent(self):
if self.__token_agent:
return self.__token_agent
self.__token_agent = ContractAgency.get_agent(
NucypherTokenAgent,
provider_uri=self.eth_provider_uri,
registry=self.registry,
)
return self.__token_agent
@property
def token_balance(self) -> NU:
"""Return this actor's current token balance"""
balance = int(self.token_agent.get_balance(address=self.checksum_address))
nu_balance = NU(balance, 'NuNit')
return nu_balance
class Operator(BaseActor):
READY_TIMEOUT = None # (None or 0) == indefinite
@ -158,25 +140,24 @@ class Operator(BaseActor):
def __init__(
self,
eth_provider_uri: str,
coordinator_provider_uri: str,
coordinator_network: str,
eth_endpoint: str,
polygon_endpoint: str,
pre_payment_method: ContractPayment,
transacting_power: TransactingPower,
signer: Signer = None,
crypto_power: CryptoPower = None,
client_password: str = None,
operator_address: Optional[ChecksumAddress] = None,
condition_provider_uris: Optional[Dict[int, List[str]]] = None,
condition_blockchain_endpoints: Optional[Dict[int, List[str]]] = None,
publish_finalization: bool = True, # TODO: Remove this
*args,
**kwargs,
):
# Falsy values may be passed down from the superclass
if not eth_provider_uri:
raise ValueError("Ethereum Provider URI is required to init an operator.")
if not coordinator_provider_uri:
raise ValueError("Polygon Provider URI is required to init an operator.")
if not eth_endpoint:
raise ValueError("Ethereum endpoint URI is required to init an operator.")
if not polygon_endpoint:
raise ValueError("Polygon endpoint URI is required to init an operator.")
if not pre_payment_method:
raise ValueError("PRE payment method is required to init an operator.")
@ -204,24 +185,21 @@ class Operator(BaseActor):
self.application_agent = ContractAgency.get_agent(
TACoApplicationAgent,
provider_uri=eth_provider_uri,
blockchain_endpoint=eth_endpoint,
registry=self.registry,
)
# TODO: registry usage (and subsequently "network") is inconsistent here
coordinator_network_registry = ContractRegistry.from_latest_publication(
domain=coordinator_network
)
registry = ContractRegistry.from_latest_publication(domain=self.network)
self.child_application_agent = ContractAgency.get_agent(
TACoChildApplicationAgent,
registry=coordinator_network_registry,
provider_uri=coordinator_provider_uri,
registry=registry,
blockchain_endpoint=polygon_endpoint,
)
self.coordinator_agent = ContractAgency.get_agent(
CoordinatorAgent,
registry=coordinator_network_registry,
provider_uri=coordinator_provider_uri,
registry=registry,
blockchain_endpoint=polygon_endpoint,
)
# track active onchain rituals
@ -242,7 +220,7 @@ class Operator(BaseActor):
) # used for secure decryption request channel
self.condition_providers = self.connect_condition_providers(
condition_provider_uris
condition_blockchain_endpoints
)
def set_provider_public_key(self) -> Union[TxReceipt, None]:
@ -266,19 +244,22 @@ class Operator(BaseActor):
return provider
def connect_condition_providers(
self, condition_provider_uris: Optional[Dict[int, List[str]]] = None
self, condition_blockchain_endpoints: Optional[Dict[int, List[str]]] = None
) -> DefaultDict[int, Set[HTTPProvider]]:
"""Multi-provider support"""
# If condition_provider_uris is None the node operator
# If condition_blockchain_endpoints is None the node operator
# did not configure any additional condition providers.
condition_provider_uris = condition_provider_uris or dict()
condition_blockchain_endpoints = condition_blockchain_endpoints or dict()
# These are the chains that the Operator will connect to for conditions evaluation (read-only).
condition_providers = defaultdict(set)
# Now, add any additional providers that were passed in.
for chain_id, condition_provider_uris in condition_provider_uris.items():
for (
chain_id,
condition_blockchain_endpoints,
) in condition_blockchain_endpoints.items():
if not self._is_permitted_condition_chain(chain_id):
# this is a safety check to prevent the Operator from connecting to
# chains that are not supported by ursulas on the network;
@ -288,7 +269,7 @@ class Operator(BaseActor):
)
providers = set()
for uri in condition_provider_uris:
for uri in condition_blockchain_endpoints:
provider = self._make_condition_provider(uri)
providers.add(provider)
@ -742,10 +723,12 @@ class Operator(BaseActor):
class PolicyAuthor(NucypherTokenActor):
"""Alice base class for blockchain operations, mocking up new policies!"""
def __init__(self, eth_provider_uri: str, *args, **kwargs):
def __init__(self, eth_endpoint: str, *args, **kwargs):
super().__init__(*args, **kwargs)
self.application_agent = ContractAgency.get_agent(
TACoApplicationAgent, registry=self.registry, provider_uri=eth_provider_uri
TACoApplicationAgent,
registry=self.registry,
blockchain_endpoint=eth_endpoint,
)
def create_policy(self, *args, **kwargs):

View File

@ -81,7 +81,7 @@ class EthereumContractAgent:
def __init__(
self,
provider_uri: str,
blockchain_endpoint: str,
registry: ContractRegistry,
contract: Optional[Contract] = None,
transaction_gas: Optional[Wei] = None,
@ -91,7 +91,7 @@ class EthereumContractAgent:
self.registry = registry
self.blockchain = BlockchainInterfaceFactory.get_or_create_interface(
eth_provider_uri=provider_uri
endpoint=blockchain_endpoint
)
if not contract: # Fetch the contract
@ -106,12 +106,14 @@ class EthereumContractAgent:
transaction_gas = EthereumContractAgent.DEFAULT_TRANSACTION_GAS_LIMITS['default']
self.transaction_gas = transaction_gas
self.log.info("Initialized new {} for {} with {} and {}".format(
self.__class__.__name__,
self.contract.address,
self.blockchain.eth_provider_uri,
str(self.registry)
))
self.log.info(
"Initialized new {} for {} with {} and {}".format(
self.__class__.__name__,
self.contract.address,
self.blockchain.endpoint,
str(self.registry),
)
)
def __repr__(self) -> str:
class_name = self.__class__.__name__
@ -845,15 +847,15 @@ class ContractAgency:
cls,
agent_class: Type[types.Agent],
registry: Optional[ContractRegistry],
provider_uri: Optional[str],
blockchain_endpoint: Optional[str],
contract_version: Optional[str] = None,
) -> types.Agent:
if not issubclass(agent_class, EthereumContractAgent):
raise TypeError("Only agent subclasses can be used from the agency.")
if not provider_uri:
if not blockchain_endpoint:
raise ValueError(
"Need to specify an Ethereum provider URI in order to get an agent from the ContractAgency"
"Need to specify a blockchain provider URI in order to get an agent from the ContractAgency"
)
if not registry:
@ -869,7 +871,7 @@ class ContractAgency:
types.Agent,
agent_class(
registry=registry,
provider_uri=provider_uri,
blockchain_endpoint=blockchain_endpoint,
),
)
cls.__agents[registry_id] = cls.__agents.get(registry_id, dict())
@ -889,7 +891,7 @@ class ContractAgency:
cls,
contract_name: str,
registry: ContractRegistry,
provider_uri: str,
blockchain_endpoint: str,
contract_version: Optional[str] = None,
) -> EthereumContractAgent:
agent_name: str = cls._contract_name_to_agent_name(name=contract_name)
@ -898,7 +900,7 @@ class ContractAgency:
agent: EthereumContractAgent = cls.get_agent(
agent_class=agent_class,
registry=registry,
provider_uri=provider_uri,
blockchain_endpoint=blockchain_endpoint,
contract_version=contract_version
)
return agent

View File

@ -0,0 +1,55 @@
from enum import Enum
from typing import NamedTuple
class ChainInfo(NamedTuple):
id: int
name: str
class EthChain(ChainInfo, Enum):
MAINNET = (1, "mainnet")
GOERLI = (5, "goerli")
SEPOLIA = (11155111, "sepolia")
class PolygonChain(ChainInfo, Enum):
MAINNET = (137, "polygon")
MUMBAI = (80001, "mumbai")
class DomainInfo(NamedTuple):
name: str
eth_chain: EthChain
polygon_chain: PolygonChain
@property
def is_testnet(self) -> bool:
return self.eth_chain != EthChain.MAINNET
class TACoDomain:
class Unrecognized(RuntimeError):
"""Raised when a provided domain name is not recognized."""
MAINNET = DomainInfo("mainnet", EthChain.MAINNET, PolygonChain.MAINNET)
LYNX = DomainInfo("lynx", EthChain.GOERLI, PolygonChain.MUMBAI)
TAPIR = DomainInfo("tapir", EthChain.SEPOLIA, PolygonChain.MUMBAI)
DEFAULT_DOMAIN_NAME: str = MAINNET.name
SUPPORTED_DOMAINS = [
MAINNET,
LYNX,
TAPIR,
]
SUPPORTED_DOMAIN_NAMES = [domain.name for domain in SUPPORTED_DOMAINS]
@classmethod
def get_domain_info(cls, domain: str) -> DomainInfo:
for taco_domain in cls.SUPPORTED_DOMAINS:
if taco_domain.name == domain:
return taco_domain
raise cls.Unrecognized(f"{domain} is not a recognized domain.")

View File

@ -6,7 +6,7 @@ from urllib.parse import urlparse
import requests
from constant_sorrow.constants import (
INSUFFICIENT_ETH,
INSUFFICIENT_FUNDS,
NO_BLOCKCHAIN_CONNECTION,
UNKNOWN_TX_STATUS,
)
@ -82,7 +82,7 @@ class BlockchainInterface:
pass
REASONS = {
INSUFFICIENT_ETH: 'insufficient funds for gas * price + value',
INSUFFICIENT_FUNDS: "insufficient funds for gas * price + value",
}
class TransactionFailed(InterfaceError):
@ -100,7 +100,7 @@ class BlockchainInterface:
self.payload = transaction_dict
self.contract_function = contract_function
self.failures = {
BlockchainInterface.REASONS[INSUFFICIENT_ETH]: self.insufficient_eth
BlockchainInterface.REASONS[INSUFFICIENT_FUNDS]: self.insufficient_funds
}
self.message = self.failures.get(self.base_message, self.default)
super().__init__(self.message, *args)
@ -120,7 +120,7 @@ class BlockchainInterface:
return balance
@property
def insufficient_eth(self) -> str:
def insufficient_funds(self) -> str:
try:
transaction_fee = self.payload['gas'] * self.payload['gasPrice']
except KeyError:
@ -132,15 +132,16 @@ class BlockchainInterface:
f'but sender only has {prettify_eth_amount(self.get_balance())}.'
return message
def __init__(self,
emitter=None, # TODO # 1754
poa: bool = None,
light: bool = False,
eth_provider_uri: str = NO_BLOCKCHAIN_CONNECTION,
eth_provider: BaseProvider = NO_BLOCKCHAIN_CONNECTION,
gas_strategy: Optional[Union[str, Callable]] = None,
max_gas_price: Optional[int] = None):
def __init__(
self,
emitter=None, # TODO # 1754
poa: bool = None,
light: bool = False,
endpoint: str = NO_BLOCKCHAIN_CONNECTION,
provider: BaseProvider = NO_BLOCKCHAIN_CONNECTION,
gas_strategy: Optional[Union[str, Callable]] = None,
max_gas_price: Optional[int] = None,
):
"""
TODO: #1502 - Move to API docs.
@ -206,8 +207,8 @@ class BlockchainInterface:
self.log = Logger('Blockchain')
self.poa = poa
self.eth_provider_uri = eth_provider_uri
self._eth_provider = eth_provider
self.endpoint = endpoint
self._provider = provider
self.w3 = NO_BLOCKCHAIN_CONNECTION
self.client = NO_BLOCKCHAIN_CONNECTION
self.is_light = light
@ -219,7 +220,7 @@ class BlockchainInterface:
self.max_gas_price = max_gas_price
def __repr__(self):
r = '{name}({uri})'.format(name=self.__class__.__name__, uri=self.eth_provider_uri)
r = "{name}({uri})".format(name=self.__class__.__name__, uri=self.endpoint)
return r
def get_blocktime(self):
@ -292,23 +293,30 @@ class BlockchainInterface:
def connect(self):
eth_provider_uri = self.eth_provider_uri
self.log.info(f"Using external Web3 Provider '{self.eth_provider_uri}'")
endpoint = self.endpoint
self.log.info(f"Using external Web3 Provider '{self.endpoint}'")
# Attach Provider
self._attach_eth_provider(eth_provider=self._eth_provider, eth_provider_uri=eth_provider_uri)
self.log.info("Connecting to {}".format(self.eth_provider_uri))
if self._eth_provider is NO_BLOCKCHAIN_CONNECTION:
self._attach_blockchain_provider(
provider=self._provider,
endpoint=endpoint,
)
self.log.info("Connecting to {}".format(self.endpoint))
if self._provider is NO_BLOCKCHAIN_CONNECTION:
raise self.NoProvider("There are no configured blockchain providers")
# Connect if not connected
try:
self.w3 = self.Web3(provider=self._eth_provider)
self.w3 = self.Web3(provider=self._provider)
self.client = EthereumClient.from_w3(w3=self.w3)
except requests.ConnectionError: # RPC
raise self.ConnectionFailed(f'Connection Failed - {str(self.eth_provider_uri)} - is RPC enabled?')
except FileNotFoundError: # IPC File Protocol
raise self.ConnectionFailed(f'Connection Failed - {str(self.eth_provider_uri)} - is IPC enabled?')
raise self.ConnectionFailed(
f"Connection Failed - {str(self.endpoint)} - is RPC enabled?"
)
except FileNotFoundError: # IPC File Protocol
raise self.ConnectionFailed(
f"Connection Failed - {str(self.endpoint)} - is IPC enabled?"
)
else:
self.attach_middleware()
@ -316,20 +324,22 @@ class BlockchainInterface:
@property
def provider(self) -> BaseProvider:
return self._eth_provider
return self._provider
def _attach_eth_provider(self,
eth_provider: Optional[BaseProvider] = None,
eth_provider_uri: str = None) -> None:
def _attach_blockchain_provider(
self,
provider: Optional[BaseProvider] = None,
endpoint: str = None,
) -> None:
"""
https://web3py.readthedocs.io/en/latest/providers.html#providers
"""
if not eth_provider_uri and not eth_provider:
if not endpoint and not provider:
raise self.NoProvider("No URI or provider instances supplied.")
if eth_provider_uri and not eth_provider:
uri_breakdown = urlparse(eth_provider_uri)
if endpoint and not provider:
uri_breakdown = urlparse(endpoint)
if uri_breakdown.scheme == 'tester':
providers = {
@ -352,19 +362,23 @@ class BlockchainInterface:
# auto-detect for file based ipc
if not provider_scheme:
if Path(eth_provider_uri).is_file():
if Path(endpoint).is_file():
# file is available - assume ipc/file scheme
provider_scheme = 'file'
self.log.info(f"Auto-detected provider scheme as 'file://' for provider {eth_provider_uri}")
provider_scheme = "file"
self.log.info(
f"Auto-detected provider scheme as 'file://' for provider {endpoint}"
)
try:
self._eth_provider = providers[provider_scheme](eth_provider_uri)
self._provider = providers[provider_scheme](endpoint)
except KeyError:
raise self.UnsupportedProvider(f"{eth_provider_uri} is an invalid or unsupported blockchain provider URI")
raise self.UnsupportedProvider(
f"{endpoint} is an invalid or unsupported blockchain provider URI"
)
else:
self.eth_provider_uri = eth_provider_uri or NO_BLOCKCHAIN_CONNECTION
self.endpoint = endpoint or NO_BLOCKCHAIN_CONNECTION
else:
self._eth_provider = eth_provider
self._provider = provider
@classmethod
def _handle_failed_transaction(cls,
@ -689,11 +703,11 @@ class BlockchainInterfaceFactory:
return cls._instance
@classmethod
def is_interface_initialized(cls, eth_provider_uri: str) -> bool:
def is_interface_initialized(cls, endpoint: str) -> bool:
"""
Returns True if there is an existing connection with an equal eth_provider_uri.
Returns True if there is an existing connection with an equal endpoint.
"""
return bool(cls._interfaces.get(eth_provider_uri, False))
return bool(cls._interfaces.get(endpoint, False))
@classmethod
def register_interface(cls,
@ -702,48 +716,59 @@ class BlockchainInterfaceFactory:
force: bool = False
) -> None:
eth_provider_uri = interface.eth_provider_uri
if (eth_provider_uri in cls._interfaces) and not force:
raise cls.InterfaceAlreadyInitialized(f"A connection already exists for {eth_provider_uri}. "
"Use .get_interface instead.")
endpoint = interface.endpoint
if (endpoint in cls._interfaces) and not force:
raise cls.InterfaceAlreadyInitialized(
f"A connection already exists for {endpoint}. "
"Use .get_interface instead."
)
cached = cls.CachedInterface(interface=interface, emitter=emitter)
cls._interfaces[eth_provider_uri] = cached
cls._interfaces[endpoint] = cached
@classmethod
def initialize_interface(cls,
eth_provider_uri: str,
emitter=None,
interface_class: Interfaces = None,
*interface_args,
**interface_kwargs
) -> None:
if not eth_provider_uri:
def initialize_interface(
cls,
endpoint: str,
emitter=None,
interface_class: Interfaces = None,
*interface_args,
**interface_kwargs,
) -> None:
if not endpoint:
# Prevent empty strings and Falsy
raise BlockchainInterface.UnsupportedProvider(f"'{eth_provider_uri}' is not a valid provider URI")
raise BlockchainInterface.UnsupportedProvider(
f"'{endpoint}' is not a valid provider URI"
)
if eth_provider_uri in cls._interfaces:
raise cls.InterfaceAlreadyInitialized(f"A connection already exists for {eth_provider_uri}. "
f"Use .get_interface instead.")
if endpoint in cls._interfaces:
raise cls.InterfaceAlreadyInitialized(
f"A connection already exists for {endpoint}. "
f"Use .get_interface instead."
)
# Interface does not exist, initialize a new one.
if not interface_class:
interface_class = cls._default_interface_class
interface = interface_class(eth_provider_uri=eth_provider_uri,
*interface_args,
**interface_kwargs)
interface = interface_class(
endpoint=endpoint, *interface_args, **interface_kwargs
)
interface.connect()
cls._interfaces[eth_provider_uri] = cls.CachedInterface(interface=interface, emitter=emitter)
cls._interfaces[endpoint] = cls.CachedInterface(
interface=interface, emitter=emitter
)
@classmethod
def get_interface(cls, eth_provider_uri: str = None) -> Interfaces:
def get_interface(cls, endpoint: str = None) -> Interfaces:
# Try to get an existing cached interface.
if eth_provider_uri:
if endpoint:
try:
cached_interface = cls._interfaces[eth_provider_uri]
cached_interface = cls._interfaces[endpoint]
except KeyError:
raise cls.InterfaceNotInitialized(f"There is no connection for {eth_provider_uri}. "
f"Call .initialize_connection, then try again.")
raise cls.InterfaceNotInitialized(
f"There is no connection for {endpoint}. "
f"Call .initialize_connection, then try again."
)
# Try to use the most recently created interface by default.
else:
@ -761,14 +786,16 @@ class BlockchainInterfaceFactory:
return interface
@classmethod
def get_or_create_interface(cls,
eth_provider_uri: str,
*interface_args,
**interface_kwargs
) -> BlockchainInterface:
def get_or_create_interface(
cls, endpoint: str, *interface_args, **interface_kwargs
) -> BlockchainInterface:
try:
interface = cls.get_interface(eth_provider_uri=eth_provider_uri)
interface = cls.get_interface(endpoint=endpoint)
except (cls.InterfaceNotInitialized, cls.NoRegisteredInterfaces):
cls.initialize_interface(eth_provider_uri=eth_provider_uri, *interface_args, **interface_kwargs)
interface = cls.get_interface(eth_provider_uri=eth_provider_uri)
cls.initialize_interface(
endpoint=endpoint,
*interface_args,
**interface_kwargs,
)
interface = cls.get_interface(endpoint=endpoint)
return interface

View File

@ -1,57 +0,0 @@
class NetworksInventory: # TODO: See #1564
MAINNET = "mainnet"
LYNX = "lynx"
IBEX = "ibex" # this is required for configuration file migrations (backwards compatibility)
ETH = "ethereum"
TAPIR = "tapir"
ORYX = "oryx"
# TODO: Use naming scheme to preserve multiple compatibility with multiple deployments to a single network?
POLYGON = 'polygon'
MUMBAI = 'mumbai'
UNKNOWN = 'unknown' # TODO: Is there a better way to signal an unknown network?
DEFAULT = MAINNET
__to_chain_id_eth = {
MAINNET: 1, # Ethereum Mainnet
IBEX: 5, # this is required for configuration file migrations (backwards compatibility)
LYNX: 5, # Goerli
TAPIR: 11155111, # Sepolia
ORYX: 5, # Goerli
}
__to_chain_id_polygon = {
# TODO: Use naming scheme?
POLYGON: 137, # Polygon Mainnet
MUMBAI: 80001, # Polygon Testnet (Mumbai)
}
ETH_NETWORKS = tuple(__to_chain_id_eth.keys())
POLY_NETWORKS = tuple(__to_chain_id_polygon.keys())
NETWORKS = ETH_NETWORKS + POLY_NETWORKS
class UnrecognizedNetwork(RuntimeError):
pass
@classmethod
def get_ethereum_chain_id(cls, network):
try:
return cls.__to_chain_id_eth[network]
except KeyError:
raise cls.UnrecognizedNetwork(network)
@classmethod
def get_polygon_chain_id(cls, network):
try:
return cls.__to_chain_id_polygon[network]
except KeyError:
raise cls.UnrecognizedNetwork(network)
@classmethod
def validate_network_name(cls, network_name: str):
if network_name not in cls.NETWORKS:
raise cls.UnrecognizedNetwork(
f"{network_name} is not a recognized network."
)

View File

@ -14,25 +14,33 @@ class ProviderError(Exception):
pass
def _get_IPC_provider(eth_provider_uri) -> BaseProvider:
uri_breakdown = urlparse(eth_provider_uri)
def _get_IPC_provider(endpoint) -> BaseProvider:
uri_breakdown = urlparse(endpoint)
from nucypher.blockchain.eth.interfaces import BlockchainInterface
return IPCProvider(ipc_path=uri_breakdown.path,
timeout=BlockchainInterface.TIMEOUT,
request_kwargs={'timeout': BlockchainInterface.TIMEOUT})
def _get_HTTP_provider(eth_provider_uri) -> BaseProvider:
def _get_HTTP_provider(endpoint) -> BaseProvider:
from nucypher.blockchain.eth.interfaces import BlockchainInterface
return HTTPProvider(endpoint_uri=eth_provider_uri, request_kwargs={'timeout': BlockchainInterface.TIMEOUT})
return HTTPProvider(
endpoint_uri=endpoint,
request_kwargs={"timeout": BlockchainInterface.TIMEOUT},
)
def _get_websocket_provider(eth_provider_uri) -> BaseProvider:
def _get_websocket_provider(endpoint) -> BaseProvider:
from nucypher.blockchain.eth.interfaces import BlockchainInterface
return WebsocketProvider(endpoint_uri=eth_provider_uri, websocket_kwargs={'timeout': BlockchainInterface.TIMEOUT})
return WebsocketProvider(
endpoint_uri=endpoint,
websocket_kwargs={"timeout": BlockchainInterface.TIMEOUT},
)
def _get_auto_provider(eth_provider_uri) -> BaseProvider:
def _get_auto_provider(endpoint) -> BaseProvider:
from web3.auto import w3
# how-automated-detection-works: https://web3py.readthedocs.io/en/latest/providers.html
connected = w3.isConnected()
@ -61,7 +69,7 @@ def _get_ethereum_tester(test_backend: Union[PyEVMBackend, MockBackend]) -> Ethe
return provider
def _get_pyevm_test_provider(eth_provider_uri) -> BaseProvider:
def _get_pyevm_test_provider(endpoint) -> BaseProvider:
""" Test provider entry-point"""
# https://github.com/ethereum/eth-tester#pyevm-experimental
pyevm_eth_tester = _get_pyevm_test_backend()
@ -69,13 +77,13 @@ def _get_pyevm_test_provider(eth_provider_uri) -> BaseProvider:
return provider
def _get_mock_test_provider(eth_provider_uri) -> BaseProvider:
def _get_mock_test_provider(endpoint) -> BaseProvider:
# https://github.com/ethereum/eth-tester#mockbackend
mock_backend = MockBackend()
provider = _get_ethereum_tester(test_backend=mock_backend)
return provider
def _get_tester_ganache(eth_provider_uri=None) -> BaseProvider:
endpoint_uri = eth_provider_uri or 'http://localhost:7545'
def _get_tester_ganache(endpoint=None) -> BaseProvider:
endpoint_uri = endpoint or "http://localhost:7545"
return HTTPProvider(endpoint_uri=endpoint_uri)

View File

@ -9,7 +9,7 @@ import requests
from requests import Response
from web3.types import ABI
from nucypher.blockchain.eth.networks import NetworksInventory
from nucypher.blockchain.eth.domains import TACoDomain
from nucypher.utilities.logging import Logger
RegistryArtifact = Dict[str, Union[str, ABI]]
@ -34,10 +34,10 @@ class RegistrySource(ABC):
"""Raised when there are no available registry sources"""
def __init__(self, domain: str, *args, **kwargs):
if domain not in NetworksInventory.NETWORKS:
if domain not in TACoDomain.SUPPORTED_DOMAIN_NAMES:
raise ValueError(
f"{self.__class__.__name__} not available for domain '{domain}'. "
f"Valid options are: {', '.join(list(NetworksInventory.NETWORKS))}"
f"Valid options are: {', '.join(list(TACoDomain.SUPPORTED_DOMAIN_NAMES))}"
)
self.domain = domain
self.data = self.get()

View File

@ -34,7 +34,9 @@ class Web3Signer(Signer):
BlockchainInterfaceFactory,
)
try:
blockchain = BlockchainInterfaceFactory.get_or_create_interface(eth_provider_uri=uri)
blockchain = BlockchainInterfaceFactory.get_or_create_interface(
endpoint=uri
)
except BlockchainInterface.UnsupportedProvider:
raise cls.InvalidSignerURI(uri)
signer = cls(client=blockchain.client)

View File

@ -20,7 +20,7 @@ class OperatorBondedTracker(SimpleTask):
application_agent = ContractAgency.get_agent(
TACoApplicationAgent,
registry=self._ursula.registry,
provider_uri=self._ursula.eth_provider_uri,
blockchain_endpoint=self._ursula.eth_endpoint,
)
# use TACo root since unbonding happens at root and not child (more immediate this way)
staking_provider_address = application_agent.get_staking_provider_from_operator(

View File

@ -34,7 +34,8 @@ class Character(Learner):
def __init__(
self,
domain: str,
eth_provider_uri: str = None,
eth_endpoint: str = None,
polygon_endpoint: str = None,
known_node_class: object = None,
is_me: bool = True,
checksum_address: str = None,
@ -113,14 +114,17 @@ class Character(Learner):
except NoSigningPower:
self._stamp = NO_SIGNING_POWER
self.eth_provider_uri = eth_provider_uri
self.eth_endpoint = eth_endpoint
self.polygon_endpoint = polygon_endpoint
self.registry = registry or ContractRegistry.from_latest_publication(
domain=domain
) # See #1580
)
# REST
self.network_middleware = network_middleware or RestMiddleware(registry=self.registry,
eth_provider_uri=eth_provider_uri)
self.network_middleware = network_middleware or RestMiddleware(
registry=self.registry, eth_endpoint=eth_endpoint
)
# Learner
Learner.__init__(self,

View File

@ -131,7 +131,7 @@ class Alice(Character, actors.PolicyAuthor):
self,
# Mode
is_me: bool = True,
eth_provider_uri: str = None,
eth_endpoint: str = None,
signer=None,
# Ownership
checksum_address: Optional[ChecksumAddress] = None,
@ -170,7 +170,7 @@ class Alice(Character, actors.PolicyAuthor):
self,
known_node_class=Ursula,
is_me=is_me,
eth_provider_uri=eth_provider_uri,
eth_endpoint=eth_endpoint,
checksum_address=checksum_address,
network_middleware=network_middleware,
*args,
@ -179,7 +179,7 @@ class Alice(Character, actors.PolicyAuthor):
if is_me: # TODO: #289
blockchain = BlockchainInterfaceFactory.get_interface(
eth_provider_uri=self.eth_provider_uri
endpoint=self.eth_endpoint
)
signer = signer or Web3Signer(
blockchain.client
@ -193,7 +193,7 @@ class Alice(Character, actors.PolicyAuthor):
domain=self.domain,
transacting_power=self.transacting_power,
registry=self.registry,
eth_provider_uri=eth_provider_uri,
eth_endpoint=eth_endpoint,
)
self.log = Logger(self.__class__.__name__)
@ -216,7 +216,7 @@ class Alice(Character, actors.PolicyAuthor):
def add_active_policy(self, active_policy):
"""
Adds a Policy object that is active on the NuCypher network to Alice's
Adds a Policy object that is active on the TACo network to Alice's
`active_policies` dictionary by the policy ID.
"""
if active_policy.hrac in self.active_policies:
@ -458,9 +458,8 @@ class Bob(Character):
self,
is_me: bool = True,
verify_node_bonding: bool = False,
eth_provider_uri: str = None,
coordinator_provider_uri: str = None, # TODO: Move to a higher level and formalize
coordinator_network: str = None, # TODO: Move to a higher level and formalize
eth_endpoint: str = None,
polygon_endpoint: str = None,
*args,
**kwargs,
) -> None:
@ -469,26 +468,22 @@ class Bob(Character):
is_me=is_me,
known_node_class=Ursula,
verify_node_bonding=verify_node_bonding,
eth_provider_uri=eth_provider_uri,
eth_endpoint=eth_endpoint,
polygon_endpoint=polygon_endpoint,
*args,
**kwargs,
)
coordinator_agent = None
if coordinator_provider_uri:
if not coordinator_network:
raise ValueError(
"If coordinator_provider_uri is set, coordinator_network must also be set"
)
if polygon_endpoint:
coordinator_agent = ContractAgency.get_agent(
CoordinatorAgent,
provider_uri=coordinator_provider_uri,
blockchain_endpoint=polygon_endpoint,
registry=ContractRegistry.from_latest_publication(
domain=coordinator_network
domain=self.domain,
),
)
self.coordinator_agent = coordinator_agent
self.coordinator_network = coordinator_network
# Cache of decrypted treasure maps
self._treasure_maps: Dict[int, TreasureMap] = {}
@ -705,9 +700,7 @@ class Bob(Character):
def _get_coordinator_agent(self) -> CoordinatorAgent:
if not self.coordinator_agent:
raise ValueError(
"No coordinator provider URI provided in Bob's constructor."
)
raise ValueError("No polygon endpoint URI provided in Bob's constructor.")
return self.coordinator_agent
@ -825,8 +818,9 @@ class Ursula(Teacher, Character, Operator):
client_password: Optional[str] = None,
transacting_power: Optional[TransactingPower] = None,
operator_signature_from_metadata=NOT_SIGNED,
eth_provider_uri: Optional[str] = None,
condition_provider_uris: Optional[Dict[int, List[str]]] = None,
eth_endpoint: Optional[str] = None,
polygon_endpoint: Optional[str] = None,
condition_blockchain_endpoints: Optional[Dict[int, List[str]]] = None,
pre_payment_method: Optional[Union[PaymentMethod, ContractPayment]] = None,
# Character
abort_on_learning_error: bool = False,
@ -844,7 +838,8 @@ class Ursula(Teacher, Character, Operator):
domain=domain,
known_node_class=Ursula,
include_self_in_the_state=True,
eth_provider_uri=eth_provider_uri,
eth_endpoint=eth_endpoint,
polygon_endpoint=polygon_endpoint,
**character_kwargs,
)
@ -863,13 +858,12 @@ class Ursula(Teacher, Character, Operator):
signer=self.signer,
crypto_power=self._crypto_power,
operator_address=operator_address,
eth_provider_uri=eth_provider_uri,
eth_endpoint=eth_endpoint,
polygon_endpoint=polygon_endpoint,
pre_payment_method=pre_payment_method,
client_password=client_password,
condition_provider_uris=condition_provider_uris,
coordinator_provider_uri=pre_payment_method.provider,
condition_blockchain_endpoints=condition_blockchain_endpoints,
transacting_power=transacting_power,
coordinator_network=pre_payment_method.network,
)
except Exception:
@ -997,11 +991,9 @@ class Ursula(Teacher, Character, Operator):
# Connect to Provider
if not BlockchainInterfaceFactory.is_interface_initialized(
eth_provider_uri=self.eth_provider_uri
endpoint=self.eth_endpoint
):
BlockchainInterfaceFactory.initialize_interface(
eth_provider_uri=self.eth_provider_uri
)
BlockchainInterfaceFactory.initialize_interface(endpoint=self.eth_endpoint)
if preflight:
self.__preflight()
@ -1189,15 +1181,15 @@ class Ursula(Teacher, Character, Operator):
return cls.from_seed_and_stake_info(seed_uri=seed_uri, *args, **kwargs)
@classmethod
def seednode_for_network(cls, network: str, provider_uri: str) -> "Ursula":
def seednode_for_domain(cls, domain: str, eth_endpoint: str) -> "Ursula":
"""Returns a default seednode ursula for a given network."""
try:
url = TEACHER_NODES[network][0]
url = TEACHER_NODES[domain][0]
except KeyError:
raise ValueError(f'"{network}" is not a known network.')
raise ValueError(f'"{domain}" is not a known domain.')
except IndexError:
raise ValueError(f'No default seednodes available for "{network}".')
ursula = cls.from_seed_and_stake_info(seed_uri=url, provider_uri=provider_uri)
raise ValueError(f'No default seednodes available for "{domain}".')
ursula = cls.from_seed_and_stake_info(seed_uri=url, eth_endpoint=eth_endpoint)
return ursula
@classmethod
@ -1205,7 +1197,7 @@ class Ursula(Teacher, Character, Operator):
cls,
teacher_uri: str,
min_stake: int,
provider_uri: str,
eth_endpoint: str,
registry: ContractRegistry = None,
network_middleware: RestMiddleware = None,
retry_attempts: int = 2,
@ -1220,7 +1212,7 @@ class Ursula(Teacher, Character, Operator):
try:
teacher = cls.from_seed_and_stake_info(
seed_uri=teacher_uri,
provider_uri=provider_uri,
eth_endpoint=eth_endpoint,
minimum_stake=min_stake,
network_middleware=network_middleware,
registry=registry,
@ -1244,14 +1236,14 @@ class Ursula(Teacher, Character, Operator):
def from_seed_and_stake_info(
cls,
seed_uri: str,
provider_uri: str,
eth_endpoint: str,
registry: ContractRegistry = None,
minimum_stake: int = 0,
network_middleware: RestMiddleware = None,
) -> Union["Ursula", "NodeSprout"]:
if network_middleware is None:
network_middleware = RestMiddleware(
registry=registry, eth_provider_uri=provider_uri
registry=registry, eth_endpoint=eth_endpoint
)
# Parse node URI
@ -1280,7 +1272,9 @@ class Ursula(Teacher, Character, Operator):
# Check the node's stake (optional)
if minimum_stake > 0 and staking_provider_address:
application_agent = ContractAgency.get_agent(
TACoApplicationAgent, provider_uri=provider_uri, registry=registry
TACoApplicationAgent,
blockchain_endpoint=eth_endpoint,
registry=registry,
)
seednode_stake = application_agent.get_authorized_stake(
staking_provider=staking_provider_address

View File

@ -42,26 +42,25 @@ class Vladimir(Ursula):
raise DevelopmentInstallationRequired(
importable_name="tests.utils.middleware.EvilMiddleWare"
)
blockchain = target_ursula.application_agent.blockchain
cls.network_middleware = EvilMiddleWare(
eth_provider_uri=blockchain.eth_provider_uri
)
eth_blockchain = target_ursula.application_agent.blockchain
cls.network_middleware = EvilMiddleWare(eth_endpoint=eth_blockchain.endpoint)
polygon_blockchain = target_ursula.child_application_agent.blockchain
crypto_power = CryptoPower(power_ups=target_ursula._default_crypto_powerups)
cls.attach_transacting_key(blockchain=blockchain)
cls.attach_transacting_key(blockchain=eth_blockchain)
# Vladimir does not care about payment.
bogus_pre_payment_method = FreeReencryptions()
bogus_pre_payment_method.provider = Mock()
bogus_pre_payment_method.agent = Mock()
bogus_pre_payment_method.network = TEMPORARY_DOMAIN
bogus_pre_payment_method.agent.blockchain.client.chain_id = (
blockchain.client.chain_id
polygon_blockchain.client.chain_id
)
mock.patch(
"mock.interfaces.MockBlockchain.client.chain_id",
new_callable=mock.PropertyMock(return_value=blockchain.client.chain_id),
new_callable=mock.PropertyMock(return_value=eth_blockchain.client.chain_id),
)
vladimir = cls(
@ -74,8 +73,9 @@ class Vladimir(Ursula):
network_middleware=cls.network_middleware,
checksum_address=cls.fraud_address,
operator_address=cls.fraud_address,
signer=Web3Signer(blockchain.client),
eth_provider_uri=blockchain.eth_provider_uri,
signer=Web3Signer(eth_blockchain.client),
eth_endpoint=eth_blockchain.endpoint,
polygon_endpoint=polygon_blockchain.endpoint,
pre_payment_method=bogus_pre_payment_method,
)

View File

@ -126,13 +126,13 @@ def handle_invalid_configuration_file(emitter: StdoutEmitter,
def collect_operator_ip_address(
emitter: StdoutEmitter, network: str, provider_uri: str, force: bool = False
emitter: StdoutEmitter, domain: str, eth_endpoint: str, force: bool = False
) -> str:
# From node swarm
try:
message = "Detecting external IP address automatically"
emitter.message(message, verbosity=2)
ip = determine_external_ip_address(network=network, provider_uri=provider_uri)
ip = determine_external_ip_address(domain=domain, eth_endpoint=eth_endpoint)
except UnknownIPAddress:
if force:
raise
@ -157,9 +157,9 @@ def perform_startup_ip_check(emitter: StdoutEmitter, ursula: Ursula, force: bool
"""
try:
external_ip = determine_external_ip_address(
network=ursula.domain,
domain=ursula.domain,
known_nodes=ursula.known_nodes,
provider_uri=ursula.eth_provider_uri,
eth_endpoint=ursula.eth_endpoint,
)
except UnknownIPAddress:
message = 'Cannot automatically determine external IP address'

View File

@ -1,5 +1,3 @@
import os
from pathlib import Path
from typing import Optional, Type
@ -8,22 +6,20 @@ import click
from tabulate import tabulate
from web3.main import Web3
from nucypher.blockchain.eth.agents import ContractAgency, NucypherTokenAgent
from nucypher.blockchain.eth.domains import TACoDomain
from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory
from nucypher.blockchain.eth.networks import NetworksInventory
from nucypher.blockchain.eth.registry import (
ContractRegistry,
)
from nucypher.blockchain.eth.signers.base import Signer
from nucypher.blockchain.eth.token import NU
from nucypher.cli.actions.configure import get_config_filepaths
from nucypher.cli.literature import (
DEFAULT_TO_LONE_CONFIG_FILE,
GENERIC_SELECT_ACCOUNT,
IGNORE_OLD_CONFIGURATION,
NO_ACCOUNTS,
NO_CONFIGURATIONS_ON_DISK,
NO_ETH_ACCOUNTS,
SELECT_NETWORK,
SELECT_DOMAIN,
SELECTED_ACCOUNT,
)
from nucypher.config.base import CharacterConfiguration
@ -36,53 +32,56 @@ from nucypher.utilities.emitters import StdoutEmitter
def select_client_account(
emitter,
eth_provider_uri: str = None,
polygon_endpoint: str = None,
signer: Signer = None,
signer_uri: str = None,
prompt: str = None,
default: int = 0,
registry: ContractRegistry = None,
show_eth_balance: bool = False,
show_nu_balance: bool = False,
show_matic_balance: bool = False,
show_staking: bool = False,
network: str = None,
domain: str = None,
poa: bool = None,
) -> str:
"""
Interactively select an ethereum wallet account from a table of nucypher account metadata.
Interactively select an ethereum wallet account from a table of account metadata.
Note: Showing ETH and/or NU balances, causes an eager blockchain connection.
Note: Showing MATIC balance causes an eager blockchain connection.
"""
if signer and signer_uri:
raise ValueError('Pass either signer or signer_uri but not both.')
if not any((eth_provider_uri, signer_uri, signer)):
if not any((polygon_endpoint, signer_uri, signer)):
raise ValueError("At least a provider URI, signer URI or signer must be provided to select an account")
if eth_provider_uri:
if polygon_endpoint:
# Connect to the blockchain in order to select an account
if not BlockchainInterfaceFactory.is_interface_initialized(eth_provider_uri=eth_provider_uri):
BlockchainInterfaceFactory.initialize_interface(eth_provider_uri=eth_provider_uri, poa=poa, emitter=emitter)
if not BlockchainInterfaceFactory.is_interface_initialized(
endpoint=polygon_endpoint
):
BlockchainInterfaceFactory.initialize_interface(
endpoint=polygon_endpoint, poa=poa, emitter=emitter
)
if not signer_uri:
signer_uri = eth_provider_uri
signer_uri = polygon_endpoint
blockchain = BlockchainInterfaceFactory.get_interface(eth_provider_uri=eth_provider_uri)
blockchain = BlockchainInterfaceFactory.get_interface(endpoint=polygon_endpoint)
if signer_uri and not signer:
testnet = network != NetworksInventory.MAINNET
testnet = domain != TACoDomain.MAINNET.name
signer = Signer.from_signer_uri(signer_uri, testnet=testnet)
# Display accounts info
if show_nu_balance or show_staking: # Lazy registry fetching
if show_staking: # Lazy registry fetching
if not registry:
if not network:
raise ValueError("Pass network name or registry; Got neither.")
registry = ContractRegistry.from_latest_publication(domain=network)
if not domain:
raise ValueError("Pass domain name or registry; Got neither.")
registry = ContractRegistry.from_latest_publication(domain=domain)
enumerated_accounts = dict(enumerate(signer.accounts))
if len(enumerated_accounts) < 1:
emitter.echo(NO_ETH_ACCOUNTS, color='red', bold=True)
emitter.echo(NO_ACCOUNTS, color="red", bold=True)
raise click.Abort()
elif len(enumerated_accounts) == 1:
# There are no choices if there is only one available address.
@ -90,23 +89,17 @@ def select_client_account(
# Display account info
headers = ['Account']
if show_eth_balance:
headers.append('ETH')
if show_nu_balance:
headers.append('NU')
if show_matic_balance:
headers.append("MATIC")
rows = list()
for index, account in enumerated_accounts.items():
row = [account]
if show_eth_balance:
ether_balance = Web3.from_wei(blockchain.client.get_balance(account), 'ether')
row.append(f'{ether_balance} ETH')
if show_nu_balance:
token_agent = ContractAgency.get_agent(
NucypherTokenAgent, registry=registry, provider_uri=eth_provider_uri
if show_matic_balance:
matic_balance = Web3.from_wei(
blockchain.client.get_balance(account), "ether"
)
token_balance = NU.from_units(token_agent.get_balance(account, registry))
row.append(token_balance)
row.append(f"{matic_balance} MATIC")
rows.append(row)
emitter.echo(tabulate(rows, headers=headers, showindex='always'))
@ -120,24 +113,19 @@ def select_client_account(
return chosen_account
def select_network(emitter: StdoutEmitter, network_type: str, message: Optional[str] = None) -> str:
"""Interactively select a network from nucypher networks inventory list"""
def select_domain(emitter: StdoutEmitter, message: Optional[str] = None) -> str:
"""Interactively select a domain from TACo domain inventory list"""
emitter.message(message=message or str(), color="yellow")
if network_type == NetworksInventory.ETH:
network_list = NetworksInventory.ETH_NETWORKS
elif network_type == NetworksInventory.POLYGON:
network_list = NetworksInventory.POLY_NETWORKS
else:
raise(ValueError("Network type must be either 'eth' or 'polygon'"))
rows = [[n] for n in network_list]
domain_list = TACoDomain.SUPPORTED_DOMAIN_NAMES
rows = [[n] for n in domain_list]
emitter.echo(tabulate(rows, showindex="always"))
choice = click.prompt(
SELECT_NETWORK,
SELECT_DOMAIN,
default=0,
type=click.IntRange(0, len(rows) - 1),
)
network = network_list[choice]
return network
domain = domain_list[choice]
return domain
def select_config_file(emitter: StdoutEmitter,

View File

@ -11,7 +11,7 @@ from nucypher.blockchain.eth.constants import (
AVERAGE_BLOCK_TIME_IN_SECONDS,
TACO_CONTRACT_NAMES,
)
from nucypher.blockchain.eth.networks import NetworksInventory
from nucypher.blockchain.eth.domains import TACoDomain
from nucypher.cli.config import group_general_config
from nucypher.cli.options import (
group_options,
@ -30,19 +30,19 @@ from nucypher.cli.utils import (
)
from nucypher.utilities.events import generate_events_csv_filepath
option_provider_uri = click.option(
"--provider-uri",
"provider_uri",
option_blockchain_endpoint = click.option(
"--blockchain-endpoint",
"blockchain_endpoint",
help="Blockchain provider's URI i.e. 'file:///path/to/geth.ipc'",
type=click.STRING,
required=True,
)
option_network = click.option(
"--network",
help="TACo Network",
option_domain = click.option(
"--domain",
help="TACo Domain",
type=click.STRING,
default=click.Choice(NetworksInventory.NETWORKS),
default=click.Choice(TACoDomain.SUPPORTED_DOMAIN_NAMES),
required=True,
)
@ -50,19 +50,19 @@ option_network = click.option(
class RegistryOptions:
__option_name__ = "registry_options"
def __init__(self, provider_uri, poa, registry_filepath, light, network):
self.provider_uri = provider_uri
def __init__(self, blockchain_endpoint, poa, registry_filepath, light, domain):
self.blockchain_endpoint = blockchain_endpoint
self.poa = poa
self.registry_filepath = registry_filepath
self.light = light
self.network = network
self.domain = domain
def setup(self, general_config) -> tuple:
emitter = setup_emitter(general_config)
registry = get_registry(
network=self.network, registry_filepath=self.registry_filepath
domain=self.domain, registry_filepath=self.registry_filepath
)
return emitter, registry, self.provider_uri
return emitter, registry, self.blockchain_endpoint
group_registry_options = group_options(
@ -70,8 +70,8 @@ group_registry_options = group_options(
poa=option_poa,
light=option_light,
registry_filepath=option_registry_filepath,
network=option_network,
provider_uri=option_provider_uri,
domain=option_domain,
blockchain_endpoint=option_blockchain_endpoint,
)
option_csv = click.option(
@ -117,11 +117,11 @@ def taco():
@group_general_config
def application_info(general_config, registry_options):
"""Overall information for the TACo Application."""
emitter, registry, provider_uri = registry_options.setup(
emitter, registry, blockchain_endpoint = registry_options.setup(
general_config=general_config
)
paint_application_contract_status(
emitter=emitter, registry=registry, provider_uri=provider_uri
emitter=emitter, registry=registry, eth_endpoint=blockchain_endpoint
)
@ -130,11 +130,11 @@ def application_info(general_config, registry_options):
@group_general_config
def active_providers(general_config, registry_options):
"""List of active stakers for the TACo Application"""
emitter, registry, provider_uri = registry_options.setup(
emitter, registry, blockchain_endpoint = registry_options.setup(
general_config=general_config
)
application_agent = ContractAgency.get_agent(
TACoApplicationAgent, registry=registry, provider_uri=provider_uri
TACoApplicationAgent, registry=registry, blockchain_endpoint=blockchain_endpoint
)
(
total_staked,
@ -194,12 +194,14 @@ def events(
),
)
emitter, registry, provider_uri = registry_options.setup(
emitter, registry, blockchain_endpoint = registry_options.setup(
general_config=general_config
)
contract_agent = ContractAgency.get_agent_by_contract_name(
contract_name=contract_name, registry=registry, provider_uri=provider_uri
contract_name=contract_name,
registry=registry,
blockchain_endpoint=blockchain_endpoint,
)
if from_block is None:

View File

@ -2,7 +2,6 @@ from pathlib import Path
import click
from nucypher.blockchain.eth.networks import NetworksInventory
from nucypher.cli.actions.auth import (
get_client_password,
get_nucypher_password,
@ -15,26 +14,28 @@ from nucypher.cli.actions.configure import (
handle_missing_configuration_file,
perform_startup_ip_check,
)
from nucypher.cli.actions.configure import forget as forget_nodes
from nucypher.cli.actions.configure import (
forget as forget_nodes,
)
from nucypher.cli.actions.select import (
select_client_account,
select_config_file,
select_network,
select_domain,
)
from nucypher.cli.config import group_general_config
from nucypher.cli.literature import (
DEVELOPMENT_MODE_WARNING,
FORCE_MODE_WARNING,
SELECT_OPERATOR_ACCOUNT,
SELECT_PRE_PAYMENT_NETWORK,
)
from nucypher.cli.options import (
group_options,
option_config_file,
option_config_root,
option_dev,
option_domain,
option_dry_run,
option_eth_provider_uri,
option_eth_endpoint,
option_force,
option_gas_strategy,
option_key_material,
@ -42,12 +43,9 @@ from nucypher.cli.options import (
option_lonely,
option_max_gas_price,
option_min_stake,
option_network,
option_poa,
option_policy_registry_filepath,
option_polygon_endpoint,
option_pre_payment_method,
option_pre_payment_network,
option_pre_payment_provider,
option_registry_filepath,
option_signer_uri,
option_teacher_uri,
@ -74,13 +72,12 @@ class UrsulaConfigOptions:
def __init__(
self,
eth_provider_uri: str,
eth_endpoint: str,
operator_address: str,
rest_host: str,
rest_port: int,
network: str,
domain: str,
registry_filepath: Path,
policy_registry_filepath: Path,
dev: bool,
poa: bool,
light: bool,
@ -88,19 +85,17 @@ class UrsulaConfigOptions:
max_gas_price: int, # gwei
signer_uri: str,
lonely: bool,
polygon_endpoint: str,
pre_payment_method: str,
pre_payment_provider: str,
pre_payment_network: str,
):
self.eth_provider_uri = eth_provider_uri
self.eth_endpoint = eth_endpoint
self.signer_uri = signer_uri
self.operator_address = operator_address
self.rest_host = rest_host
self.rest_port = rest_port # FIXME: not used in generate()
self.domain = network
self.domain = domain
self.registry_filepath = registry_filepath
self.policy_registry_filepath = policy_registry_filepath
self.dev = dev
self.poa = poa
self.light = light
@ -108,8 +103,7 @@ class UrsulaConfigOptions:
self.max_gas_price = max_gas_price
self.lonely = lonely
self.pre_payment_method = pre_payment_method
self.pre_payment_provider = pre_payment_provider
self.pre_payment_network = pre_payment_network
self.polygon_endpoint = polygon_endpoint
def create_config(self, emitter, config_file):
if self.dev:
@ -120,8 +114,7 @@ class UrsulaConfigOptions:
poa=self.poa,
light=self.light,
registry_filepath=self.registry_filepath,
policy_registry_filepath=self.policy_registry_filepath,
eth_provider_uri=self.eth_provider_uri,
eth_endpoint=self.eth_endpoint,
signer_uri=self.signer_uri,
gas_strategy=self.gas_strategy,
max_gas_price=self.max_gas_price,
@ -129,8 +122,7 @@ class UrsulaConfigOptions:
rest_host=self.rest_host,
rest_port=self.rest_port,
pre_payment_method=self.pre_payment_method,
pre_payment_provider=self.pre_payment_provider,
pre_payment_network=self.pre_payment_network,
polygon_endpoint=self.polygon_endpoint,
)
else:
if not config_file:
@ -143,8 +135,7 @@ class UrsulaConfigOptions:
filepath=config_file,
domain=self.domain,
registry_filepath=self.registry_filepath,
policy_registry_filepath=self.policy_registry_filepath,
eth_provider_uri=self.eth_provider_uri,
eth_endpoint=self.eth_endpoint,
signer_uri=self.signer_uri,
gas_strategy=self.gas_strategy,
max_gas_price=self.max_gas_price,
@ -153,8 +144,7 @@ class UrsulaConfigOptions:
poa=self.poa,
light=self.light,
pre_payment_method=self.pre_payment_method,
pre_payment_provider=self.pre_payment_provider,
pre_payment_network=self.pre_payment_network,
polygon_endpoint=self.polygon_endpoint,
)
except FileNotFoundError:
return handle_missing_configuration_file(character_config_class=UrsulaConfiguration, config_file=config_file)
@ -175,7 +165,7 @@ class UrsulaConfigOptions:
self.operator_address = select_client_account(
emitter=emitter,
prompt=prompt,
eth_provider_uri=self.eth_provider_uri,
polygon_endpoint=self.polygon_endpoint,
signer_uri=self.signer_uri,
)
@ -183,9 +173,9 @@ class UrsulaConfigOptions:
if not self.rest_host:
self.rest_host = collect_operator_ip_address(
emitter,
network=self.domain,
domain=self.domain,
force=force,
provider_uri=self.eth_provider_uri,
eth_endpoint=self.eth_endpoint,
)
return UrsulaConfiguration.generate(
@ -197,16 +187,14 @@ class UrsulaConfigOptions:
domain=self.domain,
operator_address=self.operator_address,
registry_filepath=self.registry_filepath,
policy_registry_filepath=self.policy_registry_filepath,
eth_provider_uri=self.eth_provider_uri,
eth_endpoint=self.eth_endpoint,
signer_uri=self.signer_uri,
gas_strategy=self.gas_strategy,
max_gas_price=self.max_gas_price,
poa=self.poa,
light=self.light,
pre_payment_method=self.pre_payment_method,
pre_payment_provider=self.pre_payment_provider,
pre_payment_network=self.pre_payment_network,
polygon_endpoint=self.polygon_endpoint,
)
def get_updates(self) -> dict:
@ -216,16 +204,14 @@ class UrsulaConfigOptions:
domain=self.domain,
operator_address=self.operator_address,
registry_filepath=self.registry_filepath,
policy_registry_filepath=self.policy_registry_filepath,
eth_provider_uri=self.eth_provider_uri,
eth_endpoint=self.eth_endpoint,
signer_uri=self.signer_uri,
gas_strategy=self.gas_strategy,
max_gas_price=self.max_gas_price,
poa=self.poa,
light=self.light,
pre_payment_method=self.pre_payment_method,
pre_payment_provider=self.pre_payment_provider,
pre_payment_network=self.pre_payment_network,
polygon_endpoint=self.polygon_endpoint,
)
# Depends on defaults being set on Configuration classes, filtrates None values
updates = {k: v for k, v in payload.items() if v is not None}
@ -235,7 +221,7 @@ class UrsulaConfigOptions:
group_config_options = group_options(
# NOTE: Don't set defaults here or they will be applied to config updates. Use the Config API.
UrsulaConfigOptions,
eth_provider_uri=option_eth_provider_uri(),
eth_endpoint=option_eth_endpoint(),
signer_uri=option_signer_uri,
gas_strategy=option_gas_strategy,
max_gas_price=option_max_gas_price,
@ -254,15 +240,13 @@ group_config_options = group_options(
help="The host port to run Ursula network services on",
type=NETWORK_PORT,
),
network=option_network(),
domain=option_domain(),
registry_filepath=option_registry_filepath,
policy_registry_filepath=option_policy_registry_filepath,
poa=option_poa,
light=option_light,
dev=option_dev,
lonely=option_lonely,
pre_payment_provider=option_pre_payment_provider,
pre_payment_network=option_pre_payment_network,
polygon_endpoint=option_polygon_endpoint,
pre_payment_method=option_pre_payment_method,
)
@ -290,7 +274,7 @@ class UrsulaCharacterOptions:
URSULA = make_cli_character(
character_config=ursula_config,
emitter=emitter,
provider_uri=ursula_config.eth_provider_uri,
eth_endpoint=ursula_config.eth_endpoint,
min_stake=self.min_stake,
teacher_uri=self.teacher_uri,
unlock_keystore=not self.config_options.dev,
@ -333,32 +317,25 @@ def init(general_config, config_options, force, config_root, key_material):
_pre_launch_warnings(emitter, dev=None, force=force)
if not config_root:
config_root = general_config.config_root
if not config_options.eth_provider_uri:
if not config_options.eth_endpoint:
raise click.BadOptionUsage(
"--eth-provider",
"--eth-endpoint",
message=click.style(
"--eth-provider is required to initialize a new ursula.", fg="red"
"--eth-endpoint is required to initialize a new ursula.", fg="red"
),
)
if not config_options.pre_payment_provider:
if not config_options.polygon_endpoint:
raise click.BadOptionUsage(
"--pre-payment-provider",
"--polygon-endpoint",
message=click.style(
"--pre-payment-provider is required to initialize a new ursula.",
"--polygon-endpoint is required to initialize a new ursula.",
fg="red",
),
)
if not config_options.domain:
config_options.domain = select_network(
config_options.domain = select_domain(
emitter,
message="Select Staking Network",
network_type=NetworksInventory.ETH,
)
if not config_options.pre_payment_network:
config_options.pre_payment_network = select_network(
emitter,
message=SELECT_PRE_PAYMENT_NETWORK,
network_type=NetworksInventory.POLYGON,
message="Select TACo Domain",
)
ursula_config = config_options.generate_config(
emitter=emitter, config_root=config_root, force=force, key_material=key_material
@ -496,9 +473,9 @@ def config(general_config, config_options, config_file, force, action):
if action == "ip-address":
rest_host = collect_operator_ip_address(
emitter=emitter,
network=config_options.domain,
domain=config_options.domain,
force=force,
provider_uri=config_options.eth_provider_uri,
eth_endpoint=config_options.eth_endpoint,
)
config_options.rest_host = rest_host
if action == "migrate":

View File

@ -43,9 +43,7 @@ nucypher {init_command}
"""
SELECT_NETWORK = "Select Network"
SELECT_PRE_PAYMENT_NETWORK = "Select PRE Payment Network"
SELECT_DOMAIN = "Select TACo Domain"
NO_CONFIGURATIONS_ON_DISK = "No {name} configurations found. Run 'nucypher {command} init' then try again."
@ -55,7 +53,7 @@ INVALID_JSON_IN_CONFIGURATION_WARNING = "Invalid JSON in Configuration File at {
INVALID_CONFIGURATION_FILE_WARNING = "Invalid Configuration at {filepath}."
NO_ETH_ACCOUNTS = "No ETH accounts were found."
NO_ACCOUNTS = "No accounts were found."
GENERIC_SELECT_ACCOUNT = "Select index of account"

View File

@ -14,7 +14,7 @@ from nucypher.cli.types import (
NETWORK_PORT,
PRE_PAYMENT_METHOD_CHOICES,
STAKED_TOKENS_RANGE,
NuCypherNetworkName,
NuCypherDomainName,
)
from nucypher.utilities.logging import Logger
@ -79,19 +79,13 @@ option_parameters = click.option(
help="Filepath to a JSON file containing additional parameters",
type=EXISTING_READABLE_FILE,
)
option_pre_payment_provider = click.option(
"--pre-payment-provider",
"pre_payment_provider",
option_polygon_endpoint = click.option(
"--polygon-endpoint",
"polygon_endpoint",
help="Connection URL for PRE payment method",
type=click.STRING,
required=False,
)
option_pre_payment_network = click.option(
"--pre-payment-network",
help="PRE payment network name",
type=click.STRING,
required=False,
) # TODO: Choices
option_pre_payment_method = click.option(
"--pre-payment-method",
help="PRE payment method name",
@ -106,11 +100,6 @@ option_registry_filepath = click.option(
help="Custom contract registry filepath",
type=EXISTING_READABLE_FILE,
)
option_policy_registry_filepath = click.option(
"--policy-registry-filepath",
help="Custom contract registry filepath for policies",
type=EXISTING_READABLE_FILE,
)
option_signer_uri = click.option("--signer", "signer_uri", "-S", default=None, type=str)
option_staking_provider = click.option(
"--staking-provider",
@ -180,13 +169,15 @@ def option_message_kit(required: bool = False, multiple: bool = False):
required=required)
def option_network(required: bool = False,
default: str = None, # NetworksInventory.DEFAULT is not a good global default (2214)
validate: bool = False):
def option_domain(
required: bool = False,
default: str = None, # nucypher.blockchain.eth.domains.DEFAULT.name is not a good global default (#2214)
validate: bool = False,
):
return click.option(
'--network',
help="NuCypher Network/Domain Name",
type=NuCypherNetworkName(validate=validate),
"--domain",
help="TACo Domain Name",
type=NuCypherDomainName(validate=validate),
required=required,
default=default)
@ -199,9 +190,10 @@ def option_policy_encrypting_key(required: bool = False):
required=required)
def option_eth_provider_uri(default=None, required: bool = False):
def option_eth_endpoint(default=None, required: bool = False):
return click.option(
'--eth-provider', 'eth_provider_uri',
"--eth-endpoint",
"eth_endpoint",
help="Blockchain provider's URI i.e. 'file:///path/to/geth.ipc'",
type=click.STRING,
required=required,

View File

@ -4,9 +4,9 @@ from nucypher.blockchain.eth.agents import (
)
def paint_application_contract_status(emitter, registry, provider_uri):
def paint_application_contract_status(emitter, registry, eth_endpoint):
application_agent = ContractAgency.get_agent(
TACoApplicationAgent, registry=registry, provider_uri=provider_uri
TACoApplicationAgent, registry=registry, blockchain_endpoint=eth_endpoint
)
blockchain = application_agent.blockchain

View File

@ -5,9 +5,15 @@ from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory
from nucypher.blockchain.eth.utils import etherscan_url
def paint_receipt_summary(emitter, receipt, chain_name: str = None, transaction_type=None, eth_provider_uri: str = None):
tx_hash = receipt['transactionHash'].hex()
emitter.echo("OK", color='green', nl=False, bold=True)
def paint_receipt_summary(
emitter,
receipt,
chain_name: str = None,
transaction_type=None,
blockchain_endpoint: str = None,
):
tx_hash = receipt["transactionHash"].hex()
emitter.echo("OK", color="green", nl=False, bold=True)
if transaction_type:
emitter.echo(f" | {transaction_type} | {tx_hash}", color='yellow', nl=False)
else:
@ -16,7 +22,9 @@ def paint_receipt_summary(emitter, receipt, chain_name: str = None, transaction_
emitter.echo(f"Block #{receipt['blockNumber']} | {receipt['blockHash'].hex()}")
if not chain_name:
blockchain = BlockchainInterfaceFactory.get_interface(eth_provider_uri=eth_provider_uri)
blockchain = BlockchainInterfaceFactory.get_interface(
endpoint=blockchain_endpoint
)
chain_name = blockchain.client.chain_name
try:
url = etherscan_url(item=tx_hash, network=chain_name)

View File

@ -10,7 +10,7 @@ from cryptography.exceptions import InternalError
from eth_utils import to_checksum_address
from nucypher_core.umbral import PublicKey
from nucypher.blockchain.eth.networks import NetworksInventory
from nucypher.blockchain.eth.domains import TACoDomain
from nucypher.blockchain.eth.token import TToken
from nucypher.policy.payment import PRE_PAYMENT_METHODS
from nucypher.utilities.networking import InvalidOperatorIP, validate_operator_ip
@ -88,21 +88,21 @@ class DecimalRange(DecimalType):
return rv
class NuCypherNetworkName(click.ParamType):
name = 'nucypher_network_name'
class NuCypherDomainName(click.ParamType):
name = "nucypher_domain_name"
def __init__(self, validate: bool = True):
self.validate = bool(validate)
def convert(self, value, param, ctx):
if self.validate:
network = str(value).lower()
if network not in NetworksInventory.ETH_NETWORKS:
domain = str(value).lower()
if domain not in TACoDomain.SUPPORTED_DOMAIN_NAMES:
self.fail(
f"'{value}' is not a recognized network. Valid options are: {list(NetworksInventory.ETH_NETWORKS)}"
f"'{value}' is not a recognized domain. Valid options are: {list(TACoDomain.SUPPORTED_DOMAIN_NAMES)}"
)
else:
return network
return domain
else:
return value

View File

@ -16,6 +16,7 @@ from nucypher.blockchain.eth.interfaces import (
)
from nucypher.blockchain.eth.registry import (
ContractRegistry,
LocalRegistrySource,
)
from nucypher.characters.base import Character
from nucypher.cli.actions.auth import (
@ -45,7 +46,7 @@ def setup_emitter(general_config, banner: str = None) -> StdoutEmitter:
def make_cli_character(
character_config,
emitter,
provider_uri: str,
eth_endpoint: str,
unlock_keystore: bool = True,
unlock_signer: bool = True,
teacher_uri: str = None,
@ -82,14 +83,14 @@ def make_cli_character(
min_stake=min_stake,
network_middleware=character_config.network_middleware,
registry=character_config.registry,
provider_uri=provider_uri,
eth_endpoint=eth_endpoint,
)
sage_nodes.append(maybe_sage_node)
CHARACTER = character_config(
known_nodes=sage_nodes,
network_middleware=character_config.network_middleware,
eth_provider_uri=provider_uri,
eth_endpoint=eth_endpoint,
**config_args,
)
@ -102,28 +103,34 @@ def make_cli_character(
def get_registry(
network: str, registry_filepath: Optional[Path] = None
domain: str, registry_filepath: Optional[Path] = None
) -> ContractRegistry:
if registry_filepath:
registry = ContractRegistry(filepath=registry_filepath)
source = LocalRegistrySource(filepath=registry_filepath)
registry = ContractRegistry(source=source)
else:
registry = ContractRegistry.from_latest_publication(domain=network)
registry = ContractRegistry.from_latest_publication(domain=domain)
return registry
def connect_to_blockchain(emitter: StdoutEmitter,
eth_provider_uri: str,
debug: bool = False,
light: bool = False
) -> BlockchainInterface:
def connect_to_blockchain(
emitter: StdoutEmitter,
blockchain_endpoint: str,
debug: bool = False,
light: bool = False,
) -> BlockchainInterface:
try:
# Note: Conditional for test compatibility.
if not BlockchainInterfaceFactory.is_interface_initialized(eth_provider_uri=eth_provider_uri):
BlockchainInterfaceFactory.initialize_interface(eth_provider_uri=eth_provider_uri,
light=light,
emitter=emitter)
if not BlockchainInterfaceFactory.is_interface_initialized(
endpoint=blockchain_endpoint
):
BlockchainInterfaceFactory.initialize_interface(
endpoint=blockchain_endpoint, light=light, emitter=emitter
)
emitter.echo(message=CONNECTING_TO_BLOCKCHAIN)
blockchain = BlockchainInterfaceFactory.get_interface(eth_provider_uri=eth_provider_uri)
blockchain = BlockchainInterfaceFactory.get_interface(
endpoint=blockchain_endpoint
)
return blockchain
except Exception as e:
if debug:

View File

@ -16,8 +16,8 @@ from constant_sorrow.constants import (
)
from eth_utils.address import is_checksum_address
from nucypher.blockchain.eth.domains import TACoDomain
from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory
from nucypher.blockchain.eth.networks import NetworksInventory
from nucypher.blockchain.eth.registry import (
ContractRegistry,
LocalRegistrySource,
@ -303,11 +303,11 @@ class CharacterConfiguration(BaseConfiguration):
'Sideways Engagement' of Character classes; a reflection of input parameters.
"""
VERSION = 7 # bump when static payload scheme changes
VERSION = 8 # bump when static payload scheme changes
CHARACTER_CLASS = NotImplemented
MNEMONIC_KEYSTORE = False
DEFAULT_DOMAIN = NetworksInventory.DEFAULT
DEFAULT_DOMAIN = TACoDomain.DEFAULT_DOMAIN_NAME
DEFAULT_NETWORK_MIDDLEWARE = RestMiddleware
TEMP_CONFIGURATION_DIR_PREFIX = 'tmp-nucypher'
SIGNER_ENVVAR = None
@ -321,7 +321,6 @@ class CharacterConfiguration(BaseConfiguration):
# Payments
DEFAULT_PRE_PAYMENT_METHOD = "SubscriptionManager"
DEFAULT_PRE_PAYMENT_NETWORK = "polygon"
# Fields specified here are *not* passed into the Character's constructor
# and can be understood as configuration fields only.
@ -334,8 +333,6 @@ class CharacterConfiguration(BaseConfiguration):
"max_gas_price", # gwei
"signer_uri",
"keystore_path",
"pre_payment_provider",
"pre_payment_network",
)
def __init__(
@ -368,20 +365,17 @@ class CharacterConfiguration(BaseConfiguration):
# Blockchain
poa: Optional[bool] = None,
light: bool = False,
eth_provider_uri: Optional[str] = None,
eth_endpoint: Optional[str] = None,
polygon_endpoint: Optional[str] = None,
gas_strategy: Union[Callable, str] = DEFAULT_GAS_STRATEGY,
max_gas_price: Optional[int] = None,
signer_uri: Optional[str] = None,
# Payments
# TODO: Resolve code prefixing below, possibly with the use of nested configuration fields
pre_payment_method: Optional[str] = None,
pre_payment_provider: Optional[str] = None,
pre_payment_network: Optional[str] = None,
# Registries
registry: Optional[ContractRegistry] = None,
registry_filepath: Optional[Path] = None,
policy_registry: Optional[ContractRegistry] = None,
policy_registry_filepath: Optional[Path] = None,
):
self.log = Logger(self.__class__.__name__)
@ -412,17 +406,16 @@ class CharacterConfiguration(BaseConfiguration):
self.registry = registry or NO_BLOCKCHAIN_CONNECTION.bool_value(False)
self.registry_filepath = registry_filepath or UNINITIALIZED_CONFIGURATION
self.policy_registry = policy_registry or NO_BLOCKCHAIN_CONNECTION.bool_value(False)
self.policy_registry_filepath = policy_registry_filepath or UNINITIALIZED_CONFIGURATION
# Blockchain
self.poa = poa
self.is_light = light
self.eth_provider_uri = eth_provider_uri or NO_BLOCKCHAIN_CONNECTION
self.eth_endpoint = eth_endpoint or NO_BLOCKCHAIN_CONNECTION
self.polygon_endpoint = polygon_endpoint or NO_BLOCKCHAIN_CONNECTION
self.signer_uri = signer_uri or None
# Learner
self.domain = domain
self.taco_domain_info = TACoDomain.get_domain_info(self.domain)
self.learn_on_same_thread = learn_on_same_thread
self.abort_on_learning_error = abort_on_learning_error
self.start_learning_now = start_learning_now
@ -442,32 +435,9 @@ class CharacterConfiguration(BaseConfiguration):
self.gas_strategy = gas_strategy
self.max_gas_price = max_gas_price # gwei
is_initialized = BlockchainInterfaceFactory.is_interface_initialized(
eth_provider_uri=self.eth_provider_uri
)
if not is_initialized and eth_provider_uri:
BlockchainInterfaceFactory.initialize_interface(
eth_provider_uri=self.eth_provider_uri,
poa=self.poa,
light=self.is_light,
emitter=emitter,
gas_strategy=self.gas_strategy,
max_gas_price=self.max_gas_price,
)
else:
self.log.warn(
f"Using existing blockchain interface connection ({self.eth_provider_uri})."
)
# TODO: this is potential fix for multichain connection, if we want to use it build it out into a loop
# for uri in eth_provider_uri (list of uris fom config):
BlockchainInterfaceFactory.get_or_create_interface(
eth_provider_uri=pre_payment_provider,
poa=self.poa,
light=self.is_light,
emitter=emitter,
gas_strategy=self.gas_strategy,
max_gas_price=self.max_gas_price,
self._connect_to_endpoints(
emitter=emitter, endpoints=[self.eth_endpoint, self.polygon_endpoint]
)
if not self.registry:
@ -483,8 +453,9 @@ class CharacterConfiguration(BaseConfiguration):
self.registry = ContractRegistry(source=source)
self.log.info(f"Using local registry ({self.registry}).")
self.testnet = self.domain != NetworksInventory.MAINNET
self.signer = Signer.from_signer_uri(self.signer_uri, testnet=self.testnet)
self.signer = Signer.from_signer_uri(
self.signer_uri, testnet=self.taco_domain_info.is_testnet
)
#
# Onchain Payments & Policies
@ -494,32 +465,9 @@ class CharacterConfiguration(BaseConfiguration):
from nucypher.config.characters import BobConfiguration
if not isinstance(self, BobConfiguration):
# if not pre_payment_provider:
# raise self.ConfigurationError("payment provider is required.")
self.pre_payment_method = (
pre_payment_method or self.DEFAULT_PRE_PAYMENT_METHOD
)
self.pre_payment_network = (
pre_payment_network or self.DEFAULT_PRE_PAYMENT_NETWORK
)
self.pre_payment_provider = pre_payment_provider or (
self.eth_provider_uri or None
) # default to L1 payments
# TODO: Dedupe
if not self.policy_registry:
if not self.policy_registry_filepath:
self.log.info("Fetching latest policy registry from source.")
self.policy_registry = ContractRegistry.from_latest_publication(
domain=self.pre_payment_network
)
else:
self.policy_registry = ContractRegistry(
filepath=self.policy_registry_filepath
)
self.log.info(
f"Using local policy registry ({self.policy_registry})."
)
if dev_mode:
self.__temp_dir = UNINITIALIZED_CONFIGURATION
@ -533,11 +481,32 @@ class CharacterConfiguration(BaseConfiguration):
# Network
self.network_middleware = network_middleware or self.DEFAULT_NETWORK_MIDDLEWARE(
registry=self.registry, eth_provider_uri=self.eth_provider_uri
registry=self.registry, eth_endpoint=self.eth_endpoint
)
super().__init__(filepath=self.config_file_location, config_root=self.config_root)
def _connect_to_endpoints(self, emitter, endpoints: List[str]) -> None:
for endpoint in endpoints:
if endpoint and endpoint != NO_BLOCKCHAIN_CONNECTION:
is_initialized = BlockchainInterfaceFactory.is_interface_initialized(
endpoint=endpoint
)
if not is_initialized:
BlockchainInterfaceFactory.initialize_interface(
endpoint=endpoint,
poa=self.poa,
light=self.is_light,
emitter=emitter,
gas_strategy=self.gas_strategy,
max_gas_price=self.max_gas_price,
)
else:
self.log.warn(
f"Using existing blockchain interface connection ({endpoint})."
)
def __call__(self, **character_kwargs):
return self.produce(**character_kwargs)
@ -703,12 +672,12 @@ class CharacterConfiguration(BaseConfiguration):
)
# Optional values (mode)
if self.eth_provider_uri:
if self.eth_endpoint:
if not self.signer_uri:
self.signer_uri = self.eth_provider_uri
self.signer_uri = self.eth_endpoint
payload.update(
dict(
eth_provider_uri=self.eth_provider_uri,
eth_endpoint=self.eth_endpoint,
poa=self.poa,
light=self.is_light,
signer_uri=self.signer_uri,
@ -717,6 +686,11 @@ class CharacterConfiguration(BaseConfiguration):
if self.registry_filepath:
payload.update(dict(registry_filepath=self.registry_filepath))
if self.polygon_endpoint:
payload.update(
polygon_endpoint=self.polygon_endpoint,
)
# Gas Price
__max_price = str(self.max_gas_price) if self.max_gas_price else None
payload.update(dict(gas_strategy=self.gas_strategy, max_gas_price=__max_price))
@ -840,8 +814,8 @@ class CharacterConfiguration(BaseConfiguration):
#
# Strategy-Based (current implementation, inflexible & hardcoded)
# 'pre_payment_strategy': 'SubscriptionManager'
# 'pre_payment_network': 'matic'
# 'pre_payment_provider': 'https:///matic.infura.io....'
# 'network': 'polygon'
# 'blockchain_endpoint': 'https:///polygon.infura.io....'
#
# Contract-Targeted (alternative implementation, flexible & generic)
# 'pre_payment': {
@ -860,9 +834,9 @@ class CharacterConfiguration(BaseConfiguration):
if pre_payment_class.ONCHAIN:
# on-chain payment strategies require a blockchain connection
pre_payment_strategy = pre_payment_class(
network=self.pre_payment_network,
eth_provider=self.pre_payment_provider,
registry=self.policy_registry,
domain=self.taco_domain_info.name,
blockchain_endpoint=self.polygon_endpoint,
registry=self.registry,
)
else:
pre_payment_strategy = pre_payment_class()

View File

@ -5,7 +5,6 @@ from typing import Dict, List, Optional
from cryptography.x509 import Certificate
from eth_utils import is_checksum_address
from nucypher.blockchain.eth.networks import NetworksInventory
from nucypher.config.base import CharacterConfiguration
from nucypher.config.constants import (
NUCYPHER_ENVVAR_ALICE_ETH_PASSWORD,
@ -36,7 +35,7 @@ class UrsulaConfiguration(CharacterConfiguration):
keystore_path: Optional[Path] = None,
rest_port: Optional[int] = None,
certificate: Optional[Certificate] = None,
condition_provider_uris: Optional[Dict[str, List[str]]] = None,
condition_blockchain_endpoints: Optional[Dict[str, List[str]]] = None,
*args,
**kwargs,
) -> None:
@ -61,35 +60,38 @@ class UrsulaConfiguration(CharacterConfiguration):
# json configurations don't allow for integer keyed dictionaries
# so convert string chain id to integer
self.condition_provider_uris = dict()
if condition_provider_uris:
for chain, providers in condition_provider_uris.items():
self.condition_blockchain_endpoints = dict()
if condition_blockchain_endpoints:
for chain, blockchain_endpoint in condition_blockchain_endpoints.items():
# convert chain from string key (for json) to integer
self.condition_provider_uris[int(chain)] = providers
self.configure_condition_provider_uris()
def configure_condition_provider_uris(self) -> None:
"""Configure default condition provider URIs for mainnet and polygon network."""
self.condition_blockchain_endpoints[int(chain)] = blockchain_endpoint
self.configure_condition_blockchain_endpoints()
def configure_condition_blockchain_endpoints(self) -> None:
"""Configure default condition provider URIs for eth and polygon network."""
# Polygon
polygon_chain_id = NetworksInventory.get_polygon_chain_id(
self.pre_payment_network
polygon_chain_id = self.taco_domain_info.polygon_chain.id
polygon_endpoints = self.condition_blockchain_endpoints.get(
polygon_chain_id, []
)
polygon_provider_uris = self.condition_provider_uris.get(polygon_chain_id, [])
if not polygon_provider_uris:
self.condition_provider_uris[polygon_chain_id] = polygon_provider_uris
if not polygon_endpoints:
self.condition_blockchain_endpoints[polygon_chain_id] = polygon_endpoints
if self.pre_payment_provider not in polygon_provider_uris:
polygon_provider_uris.append(self.pre_payment_provider)
if self.polygon_endpoint not in polygon_endpoints:
polygon_endpoints.append(self.polygon_endpoint)
# Ethereum
staking_chain_id = NetworksInventory.get_ethereum_chain_id(self.domain)
staking_provider_uris = self.condition_provider_uris.get(staking_chain_id, [])
if not staking_provider_uris:
self.condition_provider_uris[staking_chain_id] = staking_provider_uris
staking_chain_id = self.taco_domain_info.eth_chain.id
staking_chain_endpoints = self.condition_blockchain_endpoints.get(
staking_chain_id, []
)
if not staking_chain_endpoints:
self.condition_blockchain_endpoints[
staking_chain_id
] = staking_chain_endpoints
if self.eth_provider_uri not in staking_provider_uris:
staking_provider_uris.append(self.eth_provider_uri)
if self.eth_endpoint not in staking_chain_endpoints:
staking_chain_endpoints.append(self.eth_endpoint)
@classmethod
def address_from_filepath(cls, filepath: Path) -> str:
@ -114,13 +116,11 @@ class UrsulaConfiguration(CharacterConfiguration):
operator_address=self.operator_address,
rest_host=self.rest_host,
rest_port=self.rest_port,
condition_provider_uris=self.condition_provider_uris,
condition_blockchain_endpoints=self.condition_blockchain_endpoints,
# PRE Payments
# TODO: Resolve variable prefixing below (uses nested configuration fields?)
pre_payment_method=self.pre_payment_method,
pre_payment_provider=self.pre_payment_provider,
pre_payment_network=self.pre_payment_network,
)
return {**super().static_payload(), **payload}
@ -181,8 +181,6 @@ class AliceConfiguration(CharacterConfiguration):
payload = dict(
threshold=self.threshold,
shares=self.shares,
pre_payment_network=self.pre_payment_network,
pre_payment_provider=self.pre_payment_provider,
pre_payment_method=self.pre_payment_method,
rate=self.rate,
duration=self.duration,

View File

@ -5,6 +5,7 @@ from .configuration_v3_to_v4 import configuration_v3_to_v4
from .configuration_v4_to_v5 import configuration_v4_to_v5
from .configuration_v5_to_v6 import configuration_v5_to_v6
from .configuration_v6_to_v7 import configuration_v6_to_v7
from .configuration_v7_to_v8 import configuration_v7_to_v8
MIGRATIONS = OrderedDict(
{
@ -14,5 +15,6 @@ MIGRATIONS = OrderedDict(
(4, 5): configuration_v4_to_v5,
(5, 6): configuration_v5_to_v6,
(6, 7): configuration_v6_to_v7,
(7, 8): configuration_v7_to_v8,
}
)

View File

@ -1,14 +1,15 @@
from typing import Dict
from nucypher.blockchain.eth.networks import NetworksInventory
from nucypher.blockchain.eth.domains import TACoDomain
from nucypher.config.migrations.common import perform_migration
def __migration(config: Dict) -> Dict:
taco_domain_info = TACoDomain.get_domain_info(config["domain"])
eth_provider = config["eth_provider_uri"]
eth_chain_id = NetworksInventory.get_ethereum_chain_id(config["domain"])
eth_chain_id = taco_domain_info.eth_chain.id
polygon_provider = config["payment_provider"]
polygon_chain_id = NetworksInventory.get_polygon_chain_id(config["payment_network"])
polygon_chain_id = taco_domain_info.polygon_chain.id
if "condition_provider_uris" in config:
return config
config["condition_provider_uris"] = {

View File

@ -0,0 +1,28 @@
from typing import Dict
from nucypher.config.migrations.common import perform_migration
def __migration(config: Dict) -> Dict:
# deprecations
del config["pre_payment_network"]
# eth_provider_uri -> eth_endpoint
config["eth_endpoint"] = config["eth_provider_uri"]
del config["eth_provider_uri"]
# pre_payment_provider -> polygon_endpoint
config["polygon_endpoint"] = config["pre_payment_provider"]
del config["pre_payment_provider"]
# condition_provider_uris -> condition_blockchain_endpoints
config["condition_blockchain_endpoints"] = config["condition_provider_uris"]
del config["condition_provider_uris"]
return config
def configuration_v7_to_v8(filepath) -> None:
perform_migration(
old_version=7, new_version=8, migration=__migration, filepath=filepath
)

View File

@ -28,19 +28,17 @@ class NucypherMiddlewareClient:
def __init__(
self,
eth_provider_uri: Optional[str],
eth_endpoint: Optional[str],
registry: Optional[ContractRegistry] = None,
storage: Optional[NodeStorage] = None,
*args,
**kwargs,
):
if not eth_provider_uri:
raise ValueError(
"eth_provider_uri is required for NucypherMiddlewareClient"
)
if not eth_endpoint:
raise ValueError("eth_endpoint is required for NucypherMiddlewareClient")
self.registry = registry
self.eth_provider_uri = eth_provider_uri
self.eth_endpoint = eth_endpoint
self.storage = storage or ForgetfulNodeStorage() # for certificate storage
def get_certificate(self,
@ -88,7 +86,11 @@ class NucypherMiddlewareClient:
if node_or_sprout:
if node_or_sprout is not EXEMPT_FROM_VERIFICATION:
node = node_or_sprout.mature() # Morph into a node.
node.verify_node(network_middleware_client=self, registry=self.registry, eth_provider_uri=self.eth_provider_uri)
node.verify_node(
network_middleware_client=self,
registry=self.registry,
eth_endpoint=self.eth_endpoint,
)
return self.parse_node_or_host_and_port(node_or_sprout, host, port)
def parse_node_or_host_and_port(self, node, host, port):
@ -249,8 +251,8 @@ class RestMiddleware:
def __init__(self, *args, **kwargs):
super().__init__(status=HTTPStatus.FORBIDDEN, *args, **kwargs)
def __init__(self, eth_provider_uri: str, registry=None):
self.client = self._client_class(registry=registry, eth_provider_uri=eth_provider_uri)
def __init__(self, eth_endpoint: str, registry=None):
self.client = self._client_class(registry=registry, eth_endpoint=eth_endpoint)
def request_revocation(self, ursula, revocation):
# TODO: Implement offchain revocation #2787

View File

@ -28,7 +28,7 @@ from nucypher.acumen.nicknames import Nickname
from nucypher.acumen.perception import FleetSensor
from nucypher.blockchain.eth.agents import ContractAgency, TACoApplicationAgent
from nucypher.blockchain.eth.constants import NULL_ADDRESS
from nucypher.blockchain.eth.networks import NetworksInventory
from nucypher.blockchain.eth.domains import TACoDomain
from nucypher.blockchain.eth.registry import ContractRegistry
from nucypher.config.constants import SeednodeMetadata
from nucypher.config.storages import ForgetfulNodeStorage
@ -46,14 +46,13 @@ from nucypher.network.protocols import InterfaceInfo, SuspiciousActivity
from nucypher.utilities.logging import Logger
TEACHER_NODES = {
NetworksInventory.MAINNET: (
TACoDomain.MAINNET.name: (
'https://closest-seed.nucypher.network:9151',
'https://seeds.nucypher.network',
'https://mainnet.nucypher.network:9151',
),
NetworksInventory.LYNX: ("https://lynx.nucypher.network:9151",),
NetworksInventory.TAPIR: ("https://tapir.nucypher.network:9151",),
NetworksInventory.ORYX: ("https://oryx.nucypher.network:9151",),
TACoDomain.LYNX.name: ("https://lynx.nucypher.network:9151",),
TACoDomain.TAPIR.name: ("https://tapir.nucypher.network:9151",),
}
@ -271,8 +270,9 @@ class Learner:
self.learning_deferred = Deferred()
self.domain = domain
self.taco_domain_info = TACoDomain.get_domain_info(self.domain)
default_middleware = self.__DEFAULT_MIDDLEWARE_CLASS(
registry=self.registry, eth_provider_uri=self.eth_provider_uri
registry=self.registry, eth_endpoint=self.eth_endpoint
)
self.network_middleware = network_middleware or default_middleware
self.save_metadata = save_metadata
@ -359,7 +359,7 @@ class Learner:
maybe_sage_node = self.node_class.from_teacher_uri(
teacher_uri=uri,
min_stake=0,
provider_uri=self.eth_provider_uri,
eth_endpoint=self.eth_endpoint,
network_middleware=self.network_middleware,
registry=self.registry,
)
@ -383,7 +383,7 @@ class Learner:
seed_node = self.node_class.from_seednode_metadata(
seednode_metadata=seednode_metadata,
network_middleware=self.network_middleware,
provider_uri=self.eth_provider_uri,
eth_endpoint=self.eth_endpoint,
)
except Exception as e:
# TODO: log traceback here?
@ -472,7 +472,7 @@ class Learner:
force=force_verification_recheck,
network_middleware_client=self.network_middleware.client,
registry=registry,
eth_provider_uri=self.eth_provider_uri,
eth_endpoint=self.eth_endpoint,
)
except SSLError:
# TODO: Bucket this node as having bad TLS info - maybe it's an update that hasn't fully propagated? 567
@ -758,7 +758,7 @@ class Learner:
try:
node_on_the_other_end = self.node_class.from_seednode_metadata(
stranger.seed_node_metadata(),
provider_uri=self.provider_uri,
eth_endpoint=self.eth_endpoint,
network_middleware=self.network_middleware,
)
if node_on_the_other_end != stranger:
@ -1040,7 +1040,7 @@ class Teacher:
return bytes(response)
def _operator_is_bonded(
self, provider_uri: str, registry: ContractRegistry
self, eth_endpoint: str, registry: ContractRegistry
) -> bool:
"""
This method assumes the stamp's signature is valid and accurate.
@ -1048,7 +1048,7 @@ class Teacher:
the case that the "staking provider" isn't "staking" (e.g., all her tokens have been slashed).
"""
application_agent = ContractAgency.get_agent(
TACoApplicationAgent, provider_uri=provider_uri, registry=registry
TACoApplicationAgent, blockchain_endpoint=eth_endpoint, registry=registry
) # type: TACoApplicationAgent
staking_provider_address = application_agent.get_staking_provider_from_operator(operator_address=self.operator_address)
if staking_provider_address == NULL_ADDRESS:
@ -1056,14 +1056,14 @@ class Teacher:
return staking_provider_address == self.checksum_address
def _staking_provider_is_really_staking(
self, registry: ContractRegistry, eth_provider_uri: Optional[str] = None
self, registry: ContractRegistry, eth_endpoint: Optional[str] = None
) -> bool:
"""
This method assumes the stamp's signature is valid and accurate.
As a follow-up, this checks that the staking provider is, indeed, staking.
"""
application_agent = ContractAgency.get_agent(
TACoApplicationAgent, registry=registry, provider_uri=eth_provider_uri
TACoApplicationAgent, registry=registry, blockchain_endpoint=eth_endpoint
) # type: TACoApplicationAgent
is_staking = application_agent.is_authorized(staking_provider=self.checksum_address) # checksum address here is staking provider
return is_staking
@ -1071,7 +1071,7 @@ class Teacher:
def validate_operator(
self,
registry: ContractRegistry = None,
eth_provider_uri: Optional[str] = None,
eth_endpoint: Optional[str] = None,
) -> None:
# TODO: restore this enforcement
# if registry and not eth_provider_uri:
@ -1088,14 +1088,14 @@ class Teacher:
# On-chain staking check, if registry is present
if registry:
if not self._operator_is_bonded(
registry=registry, provider_uri=eth_provider_uri
registry=registry, eth_endpoint=eth_endpoint
): # <-- Blockchain CALL
message = f"Operator {self.operator_address} is not bonded to staking provider {self.checksum_address}"
self.log.debug(message)
raise self.UnbondedOperator(message)
if self._staking_provider_is_really_staking(
registry=registry, eth_provider_uri=eth_provider_uri
registry=registry, eth_endpoint=eth_endpoint
): # <-- Blockchain CALL
self.log.info(f"Verified operator {self}")
self.verified_operator = True
@ -1115,7 +1115,7 @@ class Teacher:
raise self.InvalidNode("Metadata signature is invalid")
def validate_metadata(
self, registry: ContractRegistry = None, eth_provider_uri: Optional[str] = None
self, registry: ContractRegistry = None, eth_endpoint: Optional[str] = None
):
# Verify the metadata signature
if not self.verified_metadata:
@ -1126,13 +1126,13 @@ class Teacher:
return
# Offline check of valid stamp signature by worker
self.validate_operator(registry=registry, eth_provider_uri=eth_provider_uri)
self.validate_operator(registry=registry, eth_endpoint=eth_endpoint)
def verify_node(
self,
network_middleware_client,
registry: ContractRegistry = None,
eth_provider_uri: Optional[str] = None,
eth_endpoint: Optional[str] = None,
certificate_filepath: Optional[Path] = None,
force: bool = False,
) -> bool:
@ -1165,7 +1165,7 @@ class Teacher:
)
# This is both the stamp's client signature and interface metadata check; May raise InvalidNode
self.validate_metadata(registry=registry, eth_provider_uri=eth_provider_uri)
self.validate_metadata(registry=registry, eth_endpoint=eth_endpoint)
# The node's metadata is valid; let's be sure the interface is in order.
if not certificate_filepath:

View File

@ -6,6 +6,7 @@ from nucypher_core import ReencryptionRequest
from web3.types import ChecksumAddress, Timestamp, TxReceipt, Wei
from nucypher.blockchain.eth.agents import ContractAgency, SubscriptionManagerAgent
from nucypher.blockchain.eth.domains import TACoDomain
from nucypher.blockchain.eth.registry import ContractRegistry
from nucypher.policy import policies
@ -64,17 +65,17 @@ class ContractPayment(PaymentMethod, ABC):
def __init__(
self,
eth_provider: str,
network: str,
blockchain_endpoint: str,
domain: str,
registry: Optional[ContractRegistry] = None,
*args,
**kwargs,
):
super().__init__(*args, **kwargs)
self.provider = eth_provider
self.network = network
self.blockchain_endpoint = blockchain_endpoint
self.taco_domain_info = TACoDomain.get_domain_info(domain)
if not registry:
registry = ContractRegistry.from_latest_publication(domain=network)
registry = ContractRegistry.from_latest_publication(domain=domain)
self.registry = registry
self.__agent = None # delay blockchain/registry reads until later
@ -84,7 +85,9 @@ class ContractPayment(PaymentMethod, ABC):
if self.__agent:
return self.__agent # get cache
agent = ContractAgency.get_agent(
agent_class=self._AGENT, provider_uri=self.provider, registry=self.registry
agent_class=self._AGENT,
blockchain_endpoint=self.blockchain_endpoint,
registry=self.registry,
)
self.__agent = agent
return self.__agent # set cache

View File

@ -22,15 +22,17 @@ def encode_constructor_arguments(web3: Web3,
return data
def connect_web3_provider(eth_provider_uri: str) -> None:
def connect_web3_provider(blockchain_endpoint: str) -> None:
"""
Convenience function for connecting to an ethereum provider now.
Convenience function for connecting to a blockchain provider now.
This may be used to optimize the startup time of some applications by
establishing the connection eagerly.
"""
from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory
if not BlockchainInterfaceFactory.is_interface_initialized(eth_provider_uri=eth_provider_uri):
BlockchainInterfaceFactory.initialize_interface(eth_provider_uri=eth_provider_uri)
interface = BlockchainInterfaceFactory.get_interface(eth_provider_uri=eth_provider_uri)
if not BlockchainInterfaceFactory.is_interface_initialized(
endpoint=blockchain_endpoint
):
BlockchainInterfaceFactory.initialize_interface(endpoint=blockchain_endpoint)
interface = BlockchainInterfaceFactory.get_interface(endpoint=blockchain_endpoint)
interface.connect()

View File

@ -69,13 +69,13 @@ def _request(url: str, certificate=None) -> Union[str, None]:
def _request_from_node(
teacher,
provider_uri: str,
eth_endpoint: str,
client: Optional[NucypherMiddlewareClient] = None,
timeout: int = 2,
log: Logger = IP_DETECTION_LOGGER,
) -> Union[str, None]:
if not client:
client = NucypherMiddlewareClient(eth_provider_uri=provider_uri)
client = NucypherMiddlewareClient(eth_endpoint=eth_endpoint)
try:
response = client.get(
node_or_sprout=teacher, path="ping", timeout=timeout
@ -100,8 +100,8 @@ def _request_from_node(
def get_external_ip_from_default_teacher(
network: str,
provider_uri: str,
domain: str,
eth_endpoint: str,
registry: Optional[ContractRegistry] = None,
log: Logger = IP_DETECTION_LOGGER,
) -> Union[str, None]:
@ -111,21 +111,21 @@ def get_external_ip_from_default_teacher(
base_error = 'Cannot determine IP using default teacher'
if network not in TEACHER_NODES:
log.debug(f'{base_error}: Unknown network "{network}".')
if domain not in TEACHER_NODES:
log.debug(f'{base_error}: Unknown domain "{domain}".')
return
node_storage = LocalFileBasedNodeStorage()
Ursula.set_cert_storage_function(node_storage.store_node_certificate)
external_ip = None
for teacher_uri in TEACHER_NODES[network]:
for teacher_uri in TEACHER_NODES[domain]:
try:
teacher = Ursula.from_teacher_uri(
teacher_uri=teacher_uri, provider_uri=provider_uri, min_stake=0
teacher_uri=teacher_uri, eth_endpoint=eth_endpoint, min_stake=0
) # TODO: Handle customized min stake here.
# TODO: Pass registry here to verify stake (not essential here since it's a hardcoded node)
external_ip = _request_from_node(teacher=teacher, provider_uri=provider_uri)
external_ip = _request_from_node(teacher=teacher, eth_endpoint=eth_endpoint)
# Found a reachable teacher, return from loop
if external_ip:
break
@ -134,7 +134,7 @@ def get_external_ip_from_default_teacher(
continue
if not external_ip:
log.debug(f'{base_error}: No teacher available for network "{network}".')
log.debug(f'{base_error}: No teacher available for domain "{domain}".')
return
return external_ip
@ -142,7 +142,7 @@ def get_external_ip_from_default_teacher(
def get_external_ip_from_known_nodes(
known_nodes: FleetSensor,
provider_uri: str,
eth_endpoint: str,
sample_size: int = 3,
log: Logger = IP_DETECTION_LOGGER,
) -> Union[str, None]:
@ -154,9 +154,9 @@ def get_external_ip_from_known_nodes(
if len(known_nodes) < sample_size:
return # There are too few known nodes
sample = random.sample(list(known_nodes), sample_size)
client = NucypherMiddlewareClient(eth_provider_uri=provider_uri)
client = NucypherMiddlewareClient(eth_endpoint=eth_endpoint)
for node in sample:
ip = _request_from_node(teacher=node, client=client, provider_uri=provider_uri)
ip = _request_from_node(teacher=node, client=client, eth_endpoint=eth_endpoint)
if ip:
log.info(f'Fetched external IP address ({ip}) from randomly selected known nodes.')
return ip
@ -171,7 +171,7 @@ def get_external_ip_from_centralized_source(log: Logger = IP_DETECTION_LOGGER) -
def determine_external_ip_address(
network: str, provider_uri: str, known_nodes: FleetSensor = None
domain: str, eth_endpoint: str, known_nodes: FleetSensor = None
) -> str:
"""
Attempts to automatically determine the external IP in the following priority:
@ -186,13 +186,13 @@ def determine_external_ip_address(
# primary source
if known_nodes:
rest_host = get_external_ip_from_known_nodes(
known_nodes=known_nodes, provider_uri=provider_uri
known_nodes=known_nodes, eth_endpoint=eth_endpoint
)
# fallback 1
if not rest_host:
rest_host = get_external_ip_from_default_teacher(
network=network, provider_uri=provider_uri
domain=domain, eth_endpoint=eth_endpoint
)
# fallback 2

View File

@ -121,9 +121,10 @@ class UrsulaInfoMetricsCollector(BaseMetricsCollector):
class BlockchainMetricsCollector(BaseMetricsCollector):
"""Collector for Blockchain specific metrics."""
def __init__(self, eth_provider_uri: str):
def __init__(self, eth_endpoint: str):
super().__init__()
self.eth_provider_uri = eth_provider_uri
self.eth_endpoint = eth_endpoint
def initialize(self, metrics_prefix: str, registry: CollectorRegistry) -> None:
self.metrics = {
@ -138,7 +139,9 @@ class BlockchainMetricsCollector(BaseMetricsCollector):
}
def _collect_internal(self) -> None:
blockchain = BlockchainInterfaceFactory.get_or_create_interface(eth_provider_uri=self.eth_provider_uri)
blockchain = BlockchainInterfaceFactory.get_or_create_interface(
endpoint=self.eth_endpoint
)
self.metrics["eth_chain_id"].set(blockchain.client.chain_id)
self.metrics["eth_current_block_number"].set(blockchain.client.block_number)
@ -150,12 +153,12 @@ class StakingProviderMetricsCollector(BaseMetricsCollector):
self,
staking_provider_address: ChecksumAddress,
contract_registry: ContractRegistry,
eth_provider_uri: str,
eth_endpoint: str,
):
super().__init__()
self.staking_provider_address = staking_provider_address
self.contract_registry = contract_registry
self.eth_provider_uri = eth_provider_uri
self.eth_endpoint = eth_endpoint
def initialize(self, metrics_prefix: str, registry: CollectorRegistry) -> None:
self.metrics = {
@ -180,7 +183,7 @@ class StakingProviderMetricsCollector(BaseMetricsCollector):
application_agent = ContractAgency.get_agent(
TACoApplicationAgent,
registry=self.contract_registry,
provider_uri=self.eth_provider_uri,
blockchain_endpoint=self.eth_endpoint,
)
authorized = application_agent.get_authorized_stake(
staking_provider=self.staking_provider_address

View File

@ -157,16 +157,14 @@ def create_metrics_collectors(ursula: "lawful.Ursula") -> List[MetricsCollector]
# Blockchain prometheus
# TODO possible include information about payment
collectors.append(
BlockchainMetricsCollector(eth_provider_uri=ursula.eth_provider_uri)
)
collectors.append(BlockchainMetricsCollector(eth_endpoint=ursula.eth_endpoint))
# Staking Provider prometheus
collectors.append(
StakingProviderMetricsCollector(
staking_provider_address=ursula.checksum_address,
contract_registry=ursula.registry,
eth_provider_uri=ursula.eth_provider_uri,
eth_endpoint=ursula.eth_endpoint,
)
)

View File

@ -27,7 +27,7 @@ from nucypher.blockchain.eth.agents import (
TACoApplicationAgent,
TACoChildApplicationAgent,
)
from nucypher.blockchain.eth.networks import NetworksInventory
from nucypher.blockchain.eth.domains import TACoDomain
from nucypher.blockchain.eth.registry import ContractRegistry
from nucypher.utilities.emitters import StdoutEmitter
from nucypher.utilities.logging import GlobalLoggerSettings
@ -42,71 +42,56 @@ emitter = StdoutEmitter(verbosity=2)
@click.command()
@click.option(
"--eth-provider",
"eth_provider_uri",
"--domain",
"domain",
help="TACo domain",
type=click.Choice(TACoDomain.SUPPORTED_DOMAIN_NAMES),
default=TACoDomain.LYNX.name,
)
@click.option(
"--eth-endpoint",
"eth_endpoint",
help="ETH staking network provider URI",
type=click.STRING,
required=True,
)
@click.option(
"--eth-staking-network",
"eth_staking_network",
help="ETH staking network",
type=click.Choice(NetworksInventory.ETH_NETWORKS),
default="lynx",
)
@click.option(
"--coordinator-provider",
"coordinator_provider_uri",
help="Coordinator network provider URI",
"--polygon-endpoint",
"polygon_endpoint",
help="Polygon network provider URI",
type=click.STRING,
required=True,
)
@click.option(
"--coordinator-network",
"coordinator_network",
help="Coordinator network",
type=click.Choice(NetworksInventory.POLY_NETWORKS),
default="mumbai",
)
def nucypher_agents(
eth_provider_uri,
eth_staking_network,
coordinator_provider_uri,
coordinator_network,
domain,
eth_endpoint,
polygon_endpoint,
):
staking_registry = ContractRegistry.from_latest_publication(
domain=eth_staking_network
)
emitter.echo(f"NOTICE: Connecting to {eth_staking_network} network", color="yellow")
registry = ContractRegistry.from_latest_publication(domain=domain)
emitter.echo(f"NOTICE: Connecting to {domain} domain", color="yellow")
taco_application_agent = ContractAgency.get_agent(
agent_class=TACoApplicationAgent,
registry=staking_registry,
provider_uri=eth_provider_uri,
registry=registry,
blockchain_endpoint=eth_endpoint,
) # type: TACoApplicationAgent
coordinator_network_registry = ContractRegistry.from_latest_publication(
domain=coordinator_network
)
emitter.echo(f"NOTICE: Connecting to {coordinator_network} network", color="yellow")
taco_child_application_agent = ContractAgency.get_agent(
agent_class=TACoChildApplicationAgent,
registry=coordinator_network_registry,
provider_uri=coordinator_provider_uri,
registry=registry,
blockchain_endpoint=polygon_endpoint,
) # type: TACoChildApplicationAgent
coordinator_agent = ContractAgency.get_agent(
agent_class=CoordinatorAgent,
registry=coordinator_network_registry,
provider_uri=coordinator_provider_uri,
registry=registry,
blockchain_endpoint=polygon_endpoint,
) # type: CoordinatorAgent
subscription_manager_agent = ContractAgency.get_agent(
agent_class=SubscriptionManagerAgent,
registry=coordinator_network_registry,
provider_uri=coordinator_provider_uri,
registry=registry,
blockchain_endpoint=polygon_endpoint,
) # type: SubscriptionManagerAgent
message = (

View File

@ -11,6 +11,7 @@ from nucypher.blockchain.eth.agents import (
CoordinatorAgent,
TACoApplicationAgent,
)
from nucypher.blockchain.eth.domains import TACoDomain
from nucypher.blockchain.eth.registry import ContractRegistry
from nucypher.blockchain.eth.signers import InMemorySigner, Signer
from nucypher.characters.lawful import Bob, Enrico
@ -43,33 +44,26 @@ def get_transacting_power(signer: Signer):
@click.command()
@click.option(
"--eth-provider",
"eth_provider_uri",
"--domain",
"domain",
help="TACo Domain",
type=click.Choice([TACoDomain.TAPIR.name, TACoDomain.LYNX.name]),
default=TACoDomain.LYNX.name,
)
@click.option(
"--eth-endpoint",
"eth_endpoint",
help="ETH staking network provider URI",
type=click.STRING,
required=True,
)
@click.option(
"--eth-staking-network",
"eth_staking_network",
help="ETH staking network",
type=click.Choice(["tapir", "lynx"]),
default="lynx",
)
@click.option(
"--coordinator-provider",
"coordinator_provider_uri",
help="Coordinator network provider URI",
"--polygon-endpoint",
"polygon_endpoint",
help="Polygon network provider URI",
type=click.STRING,
required=True,
)
@click.option(
"--coordinator-network",
"coordinator_network",
help="Coordinator network",
type=click.Choice(["mumbai"]),
default="mumbai",
)
@click.option(
"--ritual-id",
"ritual_id",
@ -117,10 +111,9 @@ def get_transacting_power(signer: Signer):
default=False,
)
def nucypher_dkg(
eth_provider_uri,
eth_staking_network,
coordinator_provider_uri,
coordinator_network,
domain,
eth_endpoint,
polygon_endpoint,
ritual_id,
signer_uri,
dkg_size,
@ -161,22 +154,18 @@ def nucypher_dkg(
),
)
coordinator_network_registry = ContractRegistry.from_latest_publication(
domain=coordinator_network
)
taco_domain_info = TACoDomain.get_domain_info(domain)
registry = ContractRegistry.from_latest_publication(domain=domain)
coordinator_agent = ContractAgency.get_agent(
agent_class=CoordinatorAgent,
registry=coordinator_network_registry,
provider_uri=coordinator_provider_uri,
registry=registry,
blockchain_endpoint=polygon_endpoint,
) # type: CoordinatorAgent
staking_network_registry = ContractRegistry.from_latest_publication(
domain=eth_staking_network
)
application_agent = ContractAgency.get_agent(
agent_class=TACoApplicationAgent,
registry=staking_network_registry,
provider_uri=eth_provider_uri,
registry=registry,
blockchain_endpoint=eth_endpoint,
) # type: TACoApplicationAgent
#
@ -188,7 +177,7 @@ def nucypher_dkg(
# Get GlobalAllowList contract
blockchain = coordinator_agent.blockchain
allow_list = blockchain.get_contract_by_name(
registry=coordinator_network_registry, contract_name=GLOBAL_ALLOW_LIST
registry=registry, contract_name=GLOBAL_ALLOW_LIST
)
#
@ -202,7 +191,7 @@ def nucypher_dkg(
emitter.echo("--------- Initiating Ritual ---------", color="yellow")
emitter.echo(
f"Commencing DKG Ritual(s) on {coordinator_network} using {account_address}",
f"Commencing DKG Ritual(s) on {taco_domain_info.polygon_chain.name} using {account_address}",
color="green",
)
@ -389,11 +378,10 @@ def nucypher_dkg(
#
emitter.echo("--------- Threshold Decryption ---------")
bob = Bob(
eth_provider_uri=eth_provider_uri,
domain=eth_staking_network,
registry=staking_network_registry,
coordinator_network=coordinator_network,
coordinator_provider_uri=coordinator_provider_uri,
domain=domain,
eth_endpoint=eth_endpoint,
polygon_endpoint=polygon_endpoint,
registry=registry,
)
bob.start_learning_loop(now=True)

View File

@ -7,12 +7,12 @@ def test_get_agent_with_different_registries(test_registry):
application_agent_1 = ContractAgency.get_agent(
TACoApplicationAgent,
registry=test_registry,
provider_uri=TEST_ETH_PROVIDER_URI,
blockchain_endpoint=TEST_ETH_PROVIDER_URI,
)
application_agent_2 = ContractAgency.get_agent(
TACoApplicationAgent,
registry=test_registry,
provider_uri=TEST_ETH_PROVIDER_URI,
blockchain_endpoint=TEST_ETH_PROVIDER_URI,
)
assert application_agent_2.registry == application_agent_1.registry == test_registry
assert application_agent_2 is application_agent_1

View File

@ -13,7 +13,9 @@ from tests.constants import TEST_ETH_PROVIDER_URI
@pytest.fixture(scope='module')
def agent(testerchain, test_registry) -> NucypherTokenAgent:
token_agent = ContractAgency.get_agent(
NucypherTokenAgent, registry=test_registry, provider_uri=TEST_ETH_PROVIDER_URI
NucypherTokenAgent,
registry=test_registry,
blockchain_endpoint=TEST_ETH_PROVIDER_URI,
)
return token_agent

View File

@ -30,7 +30,7 @@ def check(policy, bob, ursulas):
def test_grant_subscription_manager(alice, bob, ursulas):
pre_payment_method = SubscriptionManagerPayment(
eth_provider=TEST_ETH_PROVIDER_URI, network=TEMPORARY_DOMAIN
blockchain_endpoint=TEST_ETH_PROVIDER_URI, domain=TEMPORARY_DOMAIN
)
alice.pre_payment_method = pre_payment_method
policy = alice.grant(

View File

@ -137,12 +137,12 @@ def test_invalid_operators_tolerance(
force=True,
registry=test_registry,
network_middleware_client=ursula.network_middleware.client,
eth_provider_uri=ursula.eth_provider_uri,
eth_endpoint=ursula.eth_endpoint,
)
# In particular, we know that it's bonded to a staker who is really staking.
assert ursula.is_confirmed
assert ursula._staking_provider_is_really_staking(
registry=test_registry, eth_provider_uri=TEST_ETH_PROVIDER_URI
registry=test_registry, eth_endpoint=TEST_ETH_PROVIDER_URI
)
# OK. Now we learn about this new worker.
@ -161,7 +161,7 @@ def test_invalid_operators_tolerance(
# OK...so...the staker is not staking anymore ...
assert not ursula._staking_provider_is_really_staking(
registry=test_registry, eth_provider_uri=TEST_ETH_PROVIDER_URI
registry=test_registry, eth_endpoint=TEST_ETH_PROVIDER_URI
)
# ... but the worker node still is "verified" (since we're not forcing on-chain verification)
@ -176,7 +176,7 @@ def test_invalid_operators_tolerance(
force=True,
registry=test_registry,
network_middleware_client=ursula.network_middleware.client,
eth_provider_uri=TEST_ETH_PROVIDER_URI,
eth_endpoint=TEST_ETH_PROVIDER_URI,
)
#

View File

@ -16,7 +16,7 @@ def test_stakers_bond_to_ursulas(ursulas, test_registry, staking_providers):
assert len(ursulas) == len(staking_providers)
for ursula in ursulas:
ursula.validate_operator(
registry=test_registry, eth_provider_uri=TEST_ETH_PROVIDER_URI
registry=test_registry, eth_endpoint=TEST_ETH_PROVIDER_URI
)
assert ursula.verified_operator
@ -106,7 +106,7 @@ def test_vladimir_uses_his_own_signing_key(alice, ursulas, test_registry):
message = f"Operator {vladimir.operator_address} is not bonded"
with pytest.raises(vladimir.UnbondedOperator, match=message):
vladimir.validate_metadata(
registry=test_registry, eth_provider_uri=TEST_ETH_PROVIDER_URI
registry=test_registry, eth_endpoint=TEST_ETH_PROVIDER_URI
)
@ -159,9 +159,7 @@ def test_ursulas_reencrypt(ursulas, alice, bob, policy_value):
assert plaintexts == [message]
# Let's consider also that a node may be down when granting
alice.network_middleware = NodeIsDownMiddleware(
eth_provider_uri=MOCK_ETH_PROVIDER_URI
)
alice.network_middleware = NodeIsDownMiddleware(eth_endpoint=MOCK_ETH_PROVIDER_URI)
alice.network_middleware.node_is_down(ursulas[0])
with pytest.raises(Policy.NotEnoughUrsulas):

View File

@ -21,7 +21,7 @@ def test_character_transacting_power_signing(testerchain, test_registry):
signer = Character(
is_me=True,
domain=TEMPORARY_DOMAIN,
eth_provider_uri=TEST_ETH_PROVIDER_URI,
eth_endpoint=TEST_ETH_PROVIDER_URI,
registry=test_registry,
checksum_address=eth_address,
)

View File

@ -73,7 +73,7 @@ def mock_funded_account_password_keystore(
taco_application_agent = ContractAgency.get_agent(
TACoApplicationAgent,
registry=test_registry,
provider_uri=TEST_ETH_PROVIDER_URI,
blockchain_endpoint=TEST_ETH_PROVIDER_URI,
)
taco_application_agent.bond_operator(
staking_provider=provider_address,
@ -123,17 +123,15 @@ def test_ursula_and_local_keystore_signer_integration(
init_args = (
"ursula",
"init",
"--network",
TEMPORARY_DOMAIN,
"--pre-payment-network",
"--domain",
TEMPORARY_DOMAIN,
"--operator-address",
worker_account.address,
"--config-root",
str(config_root_path.absolute()),
"--eth-provider",
"--eth-endpoint",
TEST_ETH_PROVIDER_URI,
"--pre-payment-provider",
"--polygon-endpoint",
TEST_POLYGON_PROVIDER_URI,
"--rest-host",
MOCK_IP_ADDRESS,

View File

@ -27,7 +27,7 @@ from tests.utils.ursula import select_test_port, start_pytest_ursula_services
@mock.patch('glob.glob', return_value=list())
def test_missing_configuration_file(_default_filepath_mock, click_runner):
cmd_args = ('ursula', 'run', '--network', TEMPORARY_DOMAIN)
cmd_args = ("ursula", "run", "--domain", TEMPORARY_DOMAIN)
result = click_runner.invoke(nucypher_cli, cmd_args, catch_exceptions=False)
assert result.exit_code != 0
configuration_type = UrsulaConfiguration.NAME
@ -45,9 +45,9 @@ def test_ursula_run_with_prometheus_but_no_metrics_port(click_runner):
"--dry-run", # Disable twisted reactor in subprocess
"--lonely", # Do not load seednodes
"--prometheus", # Specify collection of prometheus metrics
"--eth-provider",
"--eth-endpoint",
TEST_ETH_PROVIDER_URI,
"--pre-payment-provider",
"--polygon-endpoint",
TEST_POLYGON_PROVIDER_URI,
)
@ -74,12 +74,10 @@ def test_run_lone_default_development_ursula(click_runner, ursulas, testerchain)
"--lonely", # Do not load seednodes,
"--operator-address",
ursulas[0].operator_address,
"--eth-provider",
"--eth-endpoint",
TEST_ETH_PROVIDER_URI,
"--pre-payment-provider",
"--polygon-endpoint",
TEST_ETH_PROVIDER_URI,
"--pre-payment-network",
TEMPORARY_DOMAIN,
)
result = yield threads.deferToThread(
@ -128,12 +126,10 @@ def test_ursula_learns_via_cli(click_runner, ursulas, testerchain):
"--dry-run", # Disable twisted reactor
"--operator-address",
ursulas[0].operator_address,
"--eth-provider",
"--eth-endpoint",
TEST_ETH_PROVIDER_URI,
"--pre-payment-provider",
"--polygon-endpoint",
TEST_ETH_PROVIDER_URI,
"--pre-payment-network",
TEMPORARY_DOMAIN,
)
return threads.deferToThread(
@ -180,15 +176,13 @@ def test_persistent_node_storage_integration(
init_args = (
"ursula",
"init",
"--eth-provider",
"--eth-endpoint",
TEST_ETH_PROVIDER_URI,
"--pre-payment-provider",
"--polygon-endpoint",
TEST_POLYGON_PROVIDER_URI,
"--operator-address",
another_ursula,
"--network",
TEMPORARY_DOMAIN,
"--pre-payment-network",
"--domain",
TEMPORARY_DOMAIN,
"--rest-host",
MOCK_IP_ADDRESS,

View File

@ -52,7 +52,7 @@ def erc20_evm_condition_balanceof(testerchain, test_registry):
token = ContractAgency.get_agent(
NucypherTokenAgent,
registry=test_registry,
provider_uri=TEST_ETH_PROVIDER_URI,
blockchain_endpoint=TEST_ETH_PROVIDER_URI,
)
condition = ContractCondition(
contract_address=token.contract.address,
@ -115,7 +115,7 @@ def subscription_manager_get_policy_zeroized_policy_struct_condition(
subscription_manager = ContractAgency.get_agent(
SubscriptionManagerAgent,
registry=test_registry,
provider_uri=TEST_ETH_PROVIDER_URI,
blockchain_endpoint=TEST_ETH_PROVIDER_URI,
)
condition = ContractCondition(
contract_address=subscription_manager.contract.address,
@ -135,7 +135,7 @@ def subscription_manager_is_active_policy_condition(testerchain, test_registry):
subscription_manager = ContractAgency.get_agent(
SubscriptionManagerAgent,
registry=test_registry,
provider_uri=TEST_ETH_PROVIDER_URI,
blockchain_endpoint=TEST_ETH_PROVIDER_URI,
)
condition = ContractCondition(
contract_address=subscription_manager.contract.address,
@ -157,7 +157,7 @@ def custom_context_variable_erc20_condition(
token = ContractAgency.get_agent(
NucypherTokenAgent,
registry=test_registry,
provider_uri=TEST_ETH_PROVIDER_URI,
blockchain_endpoint=TEST_ETH_PROVIDER_URI,
)
condition = ContractCondition(
contract_address=token.contract.address,

View File

@ -346,7 +346,7 @@ def test_subscription_manager_get_policy_policy_struct_condition_key_tuple_evalu
subscription_manager = ContractAgency.get_agent(
SubscriptionManagerAgent,
registry=test_registry,
provider_uri=TEST_ETH_PROVIDER_URI,
blockchain_endpoint=TEST_ETH_PROVIDER_URI,
)
# test "sponsor" key (owner is the same as sponsor for this policy)
@ -464,7 +464,7 @@ def test_subscription_manager_get_policy_policy_struct_condition_index_and_value
subscription_manager = ContractAgency.get_agent(
SubscriptionManagerAgent,
registry=test_registry,
provider_uri=TEST_POLYGON_PROVIDER_URI,
blockchain_endpoint=TEST_POLYGON_PROVIDER_URI,
)
# test "sponsor" index not equal to correct value

View File

@ -11,8 +11,11 @@ from nucypher.blockchain.eth.agents import (
TACoApplicationAgent,
TACoChildApplicationAgent,
)
from nucypher.blockchain.eth.domains import (
DomainInfo,
TACoDomain,
)
from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory
from nucypher.blockchain.eth.networks import NetworksInventory
from nucypher.blockchain.eth.registry import ContractRegistry, RegistrySourceManager
from nucypher.blockchain.eth.signers.software import Web3Signer
from nucypher.config.constants import TEMPORARY_DOMAIN
@ -25,6 +28,7 @@ from tests.constants import (
MIN_OPERATOR_SECONDS,
TEST_ETH_PROVIDER_URI,
TESTERCHAIN_CHAIN_ID,
TESTERCHAIN_CHAIN_INFO,
)
from tests.utils.blockchain import TesterBlockchain
from tests.utils.registry import ApeRegistrySource
@ -299,8 +303,8 @@ def deployed_contracts(
@pytest.fixture(scope="module", autouse=True)
def test_registry(deployed_contracts):
with tests.utils.registry.mock_registry_sources():
def test_registry(deployed_contracts, module_mocker):
with tests.utils.registry.mock_registry_sources(mocker=module_mocker):
RegistrySourceManager._FALLBACK_CHAIN = (ApeRegistrySource,)
source = ApeRegistrySource(domain=TEMPORARY_DOMAIN)
registry = ContractRegistry(source=source)
@ -312,7 +316,7 @@ def test_registry(deployed_contracts):
def testerchain(project) -> TesterBlockchain:
# Extract the web3 provider containing EthereumTester from the ape project's chain manager
provider = project.chain_manager.provider.web3.provider
testerchain = TesterBlockchain(eth_provider=provider)
testerchain = TesterBlockchain(provider=provider)
BlockchainInterfaceFactory.register_interface(interface=testerchain, force=True)
yield testerchain
@ -370,7 +374,9 @@ def staking_providers(
def coordinator_agent(testerchain, test_registry):
"""Creates a coordinator agent"""
coordinator = ContractAgency.get_agent(
CoordinatorAgent, registry=test_registry, provider_uri=TEST_ETH_PROVIDER_URI
CoordinatorAgent,
registry=test_registry,
blockchain_endpoint=TEST_ETH_PROVIDER_URI,
)
return coordinator
@ -380,7 +386,7 @@ def taco_application_agent(test_registry):
_taco_application_agent = ContractAgency.get_agent(
TACoApplicationAgent,
registry=test_registry,
provider_uri=TEST_ETH_PROVIDER_URI,
blockchain_endpoint=TEST_ETH_PROVIDER_URI,
)
return _taco_application_agent
@ -391,7 +397,7 @@ def taco_child_application_agent(testerchain, test_registry):
_taco_child_application_agent = ContractAgency.get_agent(
TACoChildApplicationAgent,
registry=test_registry,
provider_uri=TEST_ETH_PROVIDER_URI,
blockchain_endpoint=TEST_ETH_PROVIDER_URI,
)
return _taco_child_application_agent
@ -426,20 +432,20 @@ def multichain_ursulas(ursulas, multichain_ids, mock_rpc_condition):
return ursulas
@pytest.fixture(scope="session", autouse=True)
def mock_condition_blockchains(session_mocker):
@pytest.fixture(scope="module", autouse=True)
def mock_condition_blockchains(module_mocker):
"""adds testerchain's chain ID to permitted conditional chains"""
session_mocker.patch.dict(
module_mocker.patch.dict(
"nucypher.policy.conditions.evm._CONDITION_CHAINS",
{TESTERCHAIN_CHAIN_ID: "eth-tester/pyevm"},
)
session_mocker.patch.object(
NetworksInventory, "get_polygon_chain_id", return_value=TESTERCHAIN_CHAIN_ID
test_domain_info = DomainInfo(
TEMPORARY_DOMAIN, TESTERCHAIN_CHAIN_INFO, TESTERCHAIN_CHAIN_INFO
)
session_mocker.patch.object(
NetworksInventory, "get_ethereum_chain_id", return_value=TESTERCHAIN_CHAIN_ID
module_mocker.patch.object(
TACoDomain, "get_domain_info", return_value=test_domain_info
)

View File

@ -1,14 +1,12 @@
import pytest
from nucypher.blockchain.eth.clients import EthereumClient
from nucypher.blockchain.eth.signers.software import Web3Signer
from nucypher.crypto.powers import TransactingPower
from tests.constants import (
DEVELOPMENT_ETH_AIRDROP_AMOUNT,
NUMBER_OF_ETH_TEST_ACCOUNTS,
NUMBER_OF_STAKING_PROVIDERS_IN_BLOCKCHAIN_TESTS,
NUMBER_OF_URSULAS_IN_BLOCKCHAIN_TESTS,
)
# Prevents TesterBlockchain to be picked up by py.test as a test class
from tests.utils.blockchain import TesterBlockchain as _TesterBlockchain
@ -28,7 +26,7 @@ def test_testerchain_creation(testerchain, another_testerchain):
for chain in chains:
# Ensure we are testing on the correct network...
assert 'tester' in chain.eth_provider_uri
assert "tester" in chain.endpoint
# ... and that there are already some blocks mined
chain.w3.eth.w3.testing.mine(1)

View File

@ -4,11 +4,19 @@ import pytest
from eth_utils.crypto import keccak
from nucypher.blockchain.eth.actors import Operator
from nucypher.blockchain.eth.networks import NetworksInventory
from nucypher.blockchain.eth.domains import (
DomainInfo,
TACoDomain,
)
from nucypher.config.constants import TEMPORARY_DOMAIN
from nucypher.crypto.powers import TransactingPower
from nucypher.network.nodes import Learner
from nucypher.utilities.logging import GlobalLoggerSettings
from tests.constants import MOCK_IP_ADDRESS, TESTERCHAIN_CHAIN_ID
from tests.constants import (
MOCK_IP_ADDRESS,
TESTERCHAIN_CHAIN_ID,
TESTERCHAIN_CHAIN_INFO,
)
# Don't re-lock accounts in the background while making commitments
LOCK_FUNCTION = TransactingPower.lock_account
@ -134,20 +142,19 @@ def disable_check_grant_requirements(session_mocker):
session_mocker.patch(target, return_value=MOCK_IP_ADDRESS)
@pytest.fixture(scope="session", autouse=True)
def mock_condition_blockchains(session_mocker):
@pytest.fixture(scope="module", autouse=True)
def mock_condition_blockchains(module_mocker):
"""adds testerchain's chain ID to permitted conditional chains"""
session_mocker.patch.dict(
module_mocker.patch.dict(
"nucypher.policy.conditions.evm._CONDITION_CHAINS",
{TESTERCHAIN_CHAIN_ID: "eth-tester/pyevm"},
)
session_mocker.patch.object(
NetworksInventory, "get_polygon_chain_id", return_value=TESTERCHAIN_CHAIN_ID
test_domain_info = DomainInfo(
TEMPORARY_DOMAIN, TESTERCHAIN_CHAIN_INFO, TESTERCHAIN_CHAIN_INFO
)
session_mocker.patch.object(
NetworksInventory, "get_ethereum_chain_id", return_value=TESTERCHAIN_CHAIN_ID
module_mocker.patch.object(
TACoDomain, "get_domain_info", return_value=test_domain_info
)

View File

@ -7,6 +7,7 @@ from random import SystemRandom
from hexbytes import HexBytes
from web3 import Web3
from nucypher.blockchain.eth.domains import ChainInfo
from nucypher.blockchain.eth.token import NU
from nucypher.config.constants import (
NUCYPHER_ENVVAR_KEYSTORE_PASSWORD,
@ -37,7 +38,7 @@ NUMBER_OF_STAKING_PROVIDERS_IN_BLOCKCHAIN_TESTS = NUMBER_OF_URSULAS_IN_BLOCKCHAI
# Ursulas (Operators) and Staking Providers have their own account
NUMBER_OF_ETH_TEST_ACCOUNTS = NUMBER_OF_URSULAS_IN_BLOCKCHAIN_TESTS + NUMBER_OF_STAKING_PROVIDERS_IN_BLOCKCHAIN_TESTS + 10
NUMBER_OF_URSULAS_IN_DEVELOPMENT_NETWORK = NUMBER_OF_URSULAS_IN_BLOCKCHAIN_TESTS
NUMBER_OF_URSULAS_IN_DEVELOPMENT_DOMAIN = NUMBER_OF_URSULAS_IN_BLOCKCHAIN_TESTS
#
# Local Signer Keystore
@ -71,6 +72,8 @@ NUMBER_OF_ALLOCATIONS_IN_TESTS = 50 # TODO: Move to constants
TESTERCHAIN_CHAIN_ID = 131277322940537
TESTERCHAIN_CHAIN_INFO = ChainInfo(131277322940537, "eth-tester")
#
# Insecure Secrets

View File

@ -23,7 +23,6 @@ from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory
from nucypher.blockchain.eth.signers.software import KeystoreSigner
from nucypher.blockchain.eth.trackers.dkg import EventScannerTask
from nucypher.characters.lawful import Enrico, Ursula
from nucypher.config.base import CharacterConfiguration
from nucypher.config.characters import (
AliceConfiguration,
BobConfiguration,
@ -130,8 +129,8 @@ def random_address(random_account):
@pytest.fixture(scope="module")
def ursula_test_config(test_registry, temp_dir_path, testerchain):
config = make_ursula_test_configuration(
eth_provider_uri=TEST_ETH_PROVIDER_URI,
pre_payment_provider=TEST_ETH_PROVIDER_URI,
eth_endpoint=TEST_ETH_PROVIDER_URI,
polygon_endpoint=TEST_ETH_PROVIDER_URI,
test_registry=test_registry,
rest_port=select_test_port(),
operator_address=testerchain.ursulas_accounts.pop(),
@ -145,8 +144,8 @@ def ursula_test_config(test_registry, temp_dir_path, testerchain):
@pytest.fixture(scope="module")
def alice_test_config(ursulas, testerchain, test_registry):
config = make_alice_test_configuration(
eth_provider_uri=TEST_ETH_PROVIDER_URI,
pre_payment_provider=TEST_ETH_PROVIDER_URI,
eth_endpoint=TEST_ETH_PROVIDER_URI,
polygon_endpoint=TEST_ETH_PROVIDER_URI,
known_nodes=ursulas,
checksum_address=testerchain.alice_account,
test_registry=test_registry,
@ -157,9 +156,11 @@ def alice_test_config(ursulas, testerchain, test_registry):
@pytest.fixture(scope="module")
def bob_test_config(testerchain, test_registry):
config = make_bob_test_configuration(eth_provider_uri=TEST_ETH_PROVIDER_URI,
test_registry=test_registry,
checksum_address=testerchain.bob_account)
config = make_bob_test_configuration(
eth_endpoint=TEST_ETH_PROVIDER_URI,
test_registry=test_registry,
checksum_address=testerchain.bob_account,
)
yield config
config.cleanup()
@ -197,7 +198,7 @@ def enacted_policy(idle_policy, ursulas):
# cannot set them again
# deposit = NON_PAYMENT(b"0000000")
# contract_end_datetime = maya.now() + datetime.timedelta(days=5)
network_middleware = MockRestMiddleware(eth_provider_uri=TEST_ETH_PROVIDER_URI)
network_middleware = MockRestMiddleware(eth_endpoint=TEST_ETH_PROVIDER_URI)
# REST call happens here, as does population of TreasureMap.
enacted_policy = idle_policy.enact(
@ -262,8 +263,7 @@ def alice(alice_test_config, ursulas, testerchain):
@pytest.fixture(scope="module")
def bob(bob_test_config, testerchain):
bob = bob_test_config.produce(
coordinator_provider_uri=MOCK_ETH_PROVIDER_URI,
coordinator_network=TEMPORARY_DOMAIN,
polygon_endpoint=TEST_ETH_PROVIDER_URI,
)
yield bob
bob.disenchant()
@ -304,8 +304,8 @@ def lonely_ursula_maker(ursula_test_config, testerchain):
@pytest.fixture(scope="module")
def mock_registry_sources():
with tests.utils.registry.mock_registry_sources():
def mock_registry_sources(module_mocker):
with tests.utils.registry.mock_registry_sources(module_mocker):
yield
@ -323,8 +323,7 @@ def light_ursula(temp_dir_path, random_account, mocker):
KeystoreSigner, "_KeystoreSigner__get_signer", return_value=random_account
)
pre_payment_method = SubscriptionManagerPayment(
eth_provider=MOCK_ETH_PROVIDER_URI,
network=TEMPORARY_DOMAIN,
blockchain_endpoint=MOCK_ETH_PROVIDER_URI, domain=TEMPORARY_DOMAIN
)
mocker.patch.object(
@ -338,7 +337,8 @@ def light_ursula(temp_dir_path, random_account, mocker):
pre_payment_method=pre_payment_method,
checksum_address=random_account.address,
operator_address=random_account.address,
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
eth_endpoint=MOCK_ETH_PROVIDER_URI,
polygon_endpoint=MOCK_ETH_PROVIDER_URI,
signer=KeystoreSigner(path=temp_dir_path),
)
return ursula
@ -434,17 +434,13 @@ def highperf_mocked_alice(
monkeymodule,
testerchain,
):
monkeymodule.setattr(
CharacterConfiguration, "DEFAULT_PRE_PAYMENT_NETWORK", TEMPORARY_DOMAIN
)
config = AliceConfiguration(
dev_mode=True,
domain=TEMPORARY_DOMAIN,
eth_provider_uri=TEST_ETH_PROVIDER_URI,
eth_endpoint=TEST_ETH_PROVIDER_URI,
checksum_address=testerchain.alice_account,
network_middleware=MockRestMiddlewareForLargeFleetTests(
eth_provider_uri=TEST_ETH_PROVIDER_URI
eth_endpoint=TEST_ETH_PROVIDER_URI
),
abort_on_learning_error=True,
save_metadata=False,
@ -462,10 +458,10 @@ def highperf_mocked_alice(
def highperf_mocked_bob(fleet_of_highperf_mocked_ursulas):
config = BobConfiguration(
dev_mode=True,
eth_provider_uri=TEST_ETH_PROVIDER_URI,
eth_endpoint=TEST_ETH_PROVIDER_URI,
domain=TEMPORARY_DOMAIN,
network_middleware=MockRestMiddlewareForLargeFleetTests(
eth_provider_uri=TEST_ETH_PROVIDER_URI
eth_endpoint=TEST_ETH_PROVIDER_URI
),
abort_on_learning_error=True,
save_metadata=False,
@ -501,9 +497,8 @@ def click_runner():
def nominal_configuration_fields():
config = UrsulaConfiguration(
dev_mode=True,
pre_payment_network=TEMPORARY_DOMAIN,
domain=TEMPORARY_DOMAIN,
eth_provider_uri=TEST_ETH_PROVIDER_URI,
eth_endpoint=TEST_ETH_PROVIDER_URI,
)
config_fields = config.static_payload()
yield tuple(config_fields.keys())
@ -565,7 +560,7 @@ def basic_auth_file(temp_dir_path):
@pytest.fixture(scope='module')
def mock_rest_middleware():
return MockRestMiddleware(eth_provider_uri=TEST_ETH_PROVIDER_URI)
return MockRestMiddleware(eth_endpoint=TEST_ETH_PROVIDER_URI)
#

View File

@ -83,9 +83,7 @@ def test_use_external_cache(enacted_policy, bob, ursulas):
ursulas = list(ursulas)
# All Ursulas are down except for two
bob.network_middleware = NodeIsDownMiddleware(
eth_provider_uri=MOCK_ETH_PROVIDER_URI
)
bob.network_middleware = NodeIsDownMiddleware(eth_endpoint=MOCK_ETH_PROVIDER_URI)
for ursula in ursulas[2:]:
bob.network_middleware.node_is_down(ursula)

View File

@ -10,7 +10,7 @@ from nucypher.characters.lawful import Bob, Enrico
from nucypher.config.constants import TEMPORARY_DOMAIN
from tests.constants import (
MOCK_ETH_PROVIDER_URI,
NUMBER_OF_URSULAS_IN_DEVELOPMENT_NETWORK,
NUMBER_OF_URSULAS_IN_DEVELOPMENT_DOMAIN,
)
from tests.utils.middleware import MockRestMiddleware
@ -49,8 +49,8 @@ def test_bob_retrieves(alice, ursulas, certificates_tempdir):
bob = Bob(
domain=TEMPORARY_DOMAIN,
start_learning_now=True,
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
network_middleware=MockRestMiddleware(eth_provider_uri=MOCK_ETH_PROVIDER_URI),
eth_endpoint=MOCK_ETH_PROVIDER_URI,
network_middleware=MockRestMiddleware(eth_endpoint=MOCK_ETH_PROVIDER_URI),
abort_on_learning_error=True,
known_nodes=a_couple_of_ursulas,
)
@ -60,7 +60,7 @@ def test_bob_retrieves(alice, ursulas, certificates_tempdir):
# Alice creates a policy granting access to Bob
# Just for fun, let's assume she distributes KFrags among Ursulas unknown to Bob
shares = NUMBER_OF_URSULAS_IN_DEVELOPMENT_NETWORK - 2
shares = NUMBER_OF_URSULAS_IN_DEVELOPMENT_DOMAIN - 2
label = b'label://' + os.urandom(32)
contract_end_datetime = maya.now() + datetime.timedelta(days=5)
policy = alice.grant(

View File

@ -1,5 +1,6 @@
import pytest
from nucypher.blockchain.eth.domains import TACoDomain
from nucypher.blockchain.eth.signers.software import Web3Signer
from nucypher.characters.chaotic import (
NiceGuyEddie,
@ -22,8 +23,8 @@ def _attempt_decryption(BobClass, plaintext, testerchain):
enrico = NiceGuyEddie(encrypting_key=trinket, signer=signer)
bob = BobClass(
registry=MOCK_REGISTRY_FILEPATH,
domain="lynx",
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
domain=TACoDomain.LYNX.name,
eth_endpoint=MOCK_ETH_PROVIDER_URI,
)
definitely_false_condition = {

View File

@ -1,9 +1,11 @@
import pytest
from nucypher.config.constants import TEMPORARY_DOMAIN
def test_new_ursula_announces_herself(lonely_ursula_maker):
ursula_in_a_house, ursula_with_a_mouse = lonely_ursula_maker(
quantity=2, domain="useless_domain"
quantity=2, domain=TEMPORARY_DOMAIN
)
# Neither Ursula knows about the other.
@ -36,8 +38,8 @@ def test_goerli_and_mumbai_as_conditions_providers(lonely_ursula_maker):
with pytest.raises(NotImplementedError):
_ursula_who_tries_to_connect_to_an_invalid_chain = lonely_ursula_maker(
quantity=1,
domain="useless_domain",
condition_provider_uris={
domain=TEMPORARY_DOMAIN,
condition_blockchain_endpoints={
INVALID_CHAIN_ID: "this is a provider URI, but it doesn't matter what we pass here because the chain_id is invalid."
},
)

View File

@ -12,9 +12,8 @@ from nucypher.blockchain.eth.clients import EthereumClient
from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory
from nucypher.blockchain.eth.signers import KeystoreSigner
from nucypher.blockchain.eth.signers.software import Web3Signer
from nucypher.blockchain.eth.token import NU
from nucypher.cli.actions.select import select_client_account
from nucypher.cli.literature import GENERIC_SELECT_ACCOUNT, NO_ETH_ACCOUNTS
from nucypher.cli.literature import GENERIC_SELECT_ACCOUNT, NO_ACCOUNTS
from nucypher.config.constants import TEMPORARY_DOMAIN
from tests.constants import (
MOCK_ETH_PROVIDER_URI,
@ -33,7 +32,7 @@ def test_select_client_account(
selected_account = select_client_account(
emitter=test_emitter,
signer=Web3Signer(testerchain.client),
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
polygon_endpoint=MOCK_ETH_PROVIDER_URI,
)
assert selected_account, "Account selection returned Falsy instead of an address"
assert isinstance(selected_account, str), "Selection is not a str"
@ -56,10 +55,10 @@ def test_select_client_account_with_no_accounts(
select_client_account(
emitter=test_emitter,
signer=Web3Signer(testerchain.client),
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
polygon_endpoint=MOCK_ETH_PROVIDER_URI,
)
captured = capsys.readouterr()
assert NO_ETH_ACCOUNTS in captured.out
assert NO_ACCOUNTS in captured.out
def test_select_client_account_ambiguous_source(
@ -120,7 +119,9 @@ def test_select_client_account_valid_sources(
# From pre-initialized Provider
mock_stdin.line(str(selection))
expected_account = testerchain.client.accounts[selection]
selected_account = select_client_account(emitter=test_emitter, eth_provider_uri=MOCK_ETH_PROVIDER_URI)
selected_account = select_client_account(
emitter=test_emitter, polygon_endpoint=MOCK_ETH_PROVIDER_URI
)
assert selected_account == expected_account
assert mock_stdin.empty()
captured = capsys.readouterr()
@ -136,7 +137,7 @@ def test_select_client_account_valid_sources(
BlockchainInterfaceFactory, "get_interface", return_value=testerchain
)
selected_account = select_client_account(
emitter=test_emitter, eth_provider_uri=MOCK_ETH_PROVIDER_URI
emitter=test_emitter, polygon_endpoint=MOCK_ETH_PROVIDER_URI
)
assert selected_account == expected_account
assert mock_stdin.empty()
@ -144,15 +145,17 @@ def test_select_client_account_valid_sources(
assert GENERIC_SELECT_ACCOUNT in captured.out and f"Selected {selection}" in captured.out
@pytest.mark.skip('fix me')
@pytest.mark.parametrize('selection,show_staking,show_eth,show_tokens,stake_info', (
(0, True, True, True, []),
(1, True, True, True, []),
(5, True, True, True, []),
(NUMBER_OF_ETH_TEST_ACCOUNTS-1, True, True, True, []),
(0, False, True, True, []),
(0, False, False, True, []),
(0, False, False, False, []),
@pytest.mark.skip("fix me")
@pytest.mark.parametrize(
"selection,show_staking,show_matic,stake_info",
(
(0, True, True, []),
(1, True, True, []),
(5, True, True, []),
(NUMBER_OF_ETH_TEST_ACCOUNTS - 1, True, True, []),
(0, False, True, []),
(0, False, False, []),
(0, False, False, []),
),
)
def test_select_client_account_with_balance_display(
@ -164,8 +167,7 @@ def test_select_client_account_with_balance_display(
mock_token_agent,
selection,
show_staking,
show_eth,
show_tokens,
show_matic,
stake_info,
):
@ -173,23 +175,27 @@ def test_select_client_account_with_balance_display(
mock_staking_agent.get_all_stakes.return_value = stake_info
# Missing network kwarg with balance display active
blockchain_read_required = any((show_staking, show_eth, show_tokens))
blockchain_read_required = any((show_staking, show_matic))
if blockchain_read_required:
with pytest.raises(ValueError, match='Pass network name or registry; Got neither.'):
select_client_account(emitter=test_emitter,
show_eth_balance=show_eth,
show_nu_balance=show_tokens,
show_staking=show_staking,
eth_provider_uri=MOCK_ETH_PROVIDER_URI)
with pytest.raises(
ValueError, match="Pass domain name or registry; Got neither."
):
select_client_account(
emitter=test_emitter,
show_matic_balance=show_matic,
show_staking=show_staking,
polygon_endpoint=MOCK_ETH_PROVIDER_URI,
)
# Good selection
mock_stdin.line(str(selection))
selected_account = select_client_account(emitter=test_emitter,
network=TEMPORARY_DOMAIN,
show_eth_balance=show_eth,
show_nu_balance=show_tokens,
show_staking=show_staking,
eth_provider_uri=MOCK_ETH_PROVIDER_URI)
selected_account = select_client_account(
emitter=test_emitter,
domain=TEMPORARY_DOMAIN,
show_matic_balance=show_matic,
show_staking=show_staking,
polygon_endpoint=MOCK_ETH_PROVIDER_URI,
)
# check for accurate selection consistency with client index
assert selected_account == testerchain.client.accounts[selection]
@ -199,10 +205,8 @@ def test_select_client_account_with_balance_display(
headers = ['Account']
if show_staking:
headers.append('Staking')
if show_eth:
headers.append('ETH')
if show_tokens:
headers.append('NU')
if show_matic:
headers.append("MATIC")
captured = capsys.readouterr()
for column_name in headers:
@ -211,11 +215,7 @@ def test_select_client_account_with_balance_display(
for account in testerchain.client.accounts:
assert account in captured.out
if show_tokens:
balance = mock_token_agent.get_balance(address=account)
assert str(NU.from_units(balance)) in captured.out
if show_eth:
if show_matic:
balance = testerchain.client.get_balance(account=account)
assert str(Web3.from_wei(balance, 'ether')) in captured.out

View File

@ -1,24 +1,18 @@
import pytest
from nucypher.blockchain.eth.networks import NetworksInventory
from nucypher.cli.actions.select import select_network
from nucypher.blockchain.eth.domains import TACoDomain
from nucypher.cli.actions.select import select_domain
__DOMAINS = TACoDomain.SUPPORTED_DOMAIN_NAMES
@pytest.mark.parametrize(
"user_input", range(0, len(NetworksInventory.ETH_NETWORKS) - 1)
)
def test_select_network_cli_action_eth(test_emitter, capsys, mock_stdin, user_input):
@pytest.mark.parametrize("user_input", range(0, len(__DOMAINS) - 1))
def test_select_network_cli_action(test_emitter, capsys, mock_stdin, user_input: int):
mock_stdin.line(str(user_input))
selection = NetworksInventory.ETH_NETWORKS[user_input]
result = select_network(emitter=test_emitter, network_type=NetworksInventory.ETH)
selection = __DOMAINS[user_input]
result = select_domain(emitter=test_emitter)
assert result == selection
assert result not in NetworksInventory.POLY_NETWORKS
captured = capsys.readouterr()
for name in NetworksInventory.ETH_NETWORKS:
for name in __DOMAINS:
assert name in captured.out
assert mock_stdin.empty()
def test_select_network_cli_action_neither(test_emitter):
with pytest.raises(Exception):
select_network(emitter=test_emitter, network_type="FAKE COIN")

View File

@ -5,7 +5,7 @@ import pytest
from nucypher.blockchain.eth.registry import ContractRegistry
from nucypher.cli.main import nucypher_cli
from nucypher.config.characters import CharacterConfiguration, UrsulaConfiguration
from nucypher.config.characters import UrsulaConfiguration
from nucypher.config.constants import (
NUCYPHER_ENVVAR_KEYSTORE_PASSWORD,
TEMPORARY_DOMAIN,
@ -40,11 +40,11 @@ def test_initialize_via_cli(
init_args = (
command,
"init",
"--network",
"--domain",
TEMPORARY_DOMAIN,
"--eth-provider",
"--eth-endpoint",
MOCK_ETH_PROVIDER_URI,
"--pre-payment-provider",
"--polygon-endpoint",
TEST_ETH_PROVIDER_URI,
"--config-root",
str(custom_filepath.absolute()),
@ -82,9 +82,6 @@ def test_reconfigure_via_cli(
monkeypatch.setattr(
ContractRegistry, "from_latest_publication", fake_get_latest_registry
)
monkeypatch.setattr(
CharacterConfiguration, "DEFAULT_PRE_PAYMENT_NETWORK", TEMPORARY_DOMAIN
)
custom_config_filepath = custom_filepath / config_class.generate_filename()
@ -103,13 +100,18 @@ def test_reconfigure_via_cli(
# Read pre-edit state
config = config_class.from_configuration_file(custom_config_filepath)
assert config.eth_provider_uri != TEST_ETH_PROVIDER_URI
assert config.eth_endpoint != TEST_ETH_PROVIDER_URI
del config
# Write
view_args = (config_class.CHARACTER_CLASS.__name__.lower(), 'config',
'--config-file', str(custom_config_filepath.absolute()),
'--eth-provider', TEST_ETH_PROVIDER_URI)
view_args = (
config_class.CHARACTER_CLASS.__name__.lower(),
"config",
"--config-file",
str(custom_config_filepath.absolute()),
"--eth-endpoint",
TEST_ETH_PROVIDER_URI,
)
result = click_runner.invoke(nucypher_cli, view_args, env=ENV)
assert result.exit_code == 0
@ -121,4 +123,4 @@ def test_reconfigure_via_cli(
assert str(custom_filepath) in result.output
# After editing the fields have been updated
assert config.eth_provider_uri == TEST_ETH_PROVIDER_URI
assert config.eth_endpoint == TEST_ETH_PROVIDER_URI

View File

@ -62,15 +62,13 @@ def test_corrupted_configuration(
init_args = (
"ursula",
"init",
"--eth-provider",
"--eth-endpoint",
MOCK_ETH_PROVIDER_URI,
"--pre-payment-provider",
"--polygon-endpoint",
TEST_POLYGON_PROVIDER_URI,
"--operator-address",
another_ursula,
"--network",
TEMPORARY_DOMAIN,
"--pre-payment-network",
"--domain",
TEMPORARY_DOMAIN,
"--rest-host",
MOCK_IP_ADDRESS,
@ -105,13 +103,11 @@ def test_corrupted_configuration(
init_args = (
"ursula",
"init",
"--network",
"--domain",
TEMPORARY_DOMAIN,
"--pre-payment-network",
TEMPORARY_DOMAIN,
"--eth-provider",
"--eth-endpoint",
MOCK_ETH_PROVIDER_URI,
"--pre-payment-provider",
"--polygon-endpoint",
TEST_POLYGON_PROVIDER_URI,
"--operator-address",
another_ursula,

View File

@ -34,11 +34,11 @@ def test_ursula_startup_ip_checkup(click_runner, mocker):
args = (
"ursula",
"init",
"--network",
"--domain",
TEMPORARY_DOMAIN,
"--eth-provider",
"--eth-endpoint",
MOCK_ETH_PROVIDER_URI,
"--pre-payment-provider",
"--polygon-endpoint",
TEST_POLYGON_PROVIDER_URI,
"--force",
)
@ -52,12 +52,12 @@ def test_ursula_startup_ip_checkup(click_runner, mocker):
args = (
"ursula",
"init",
"--network",
"--domain",
TEMPORARY_DOMAIN,
"--force",
"--eth-provider",
"--eth-endpoint",
MOCK_ETH_PROVIDER_URI,
"--pre-payment-provider",
"--polygon-endpoint",
TEST_POLYGON_PROVIDER_URI,
)
result = click_runner.invoke(
@ -70,12 +70,12 @@ def test_ursula_startup_ip_checkup(click_runner, mocker):
args = (
"ursula",
"init",
"--network",
"--domain",
TEMPORARY_DOMAIN,
"--force",
"--eth-provider",
"--eth-endpoint",
MOCK_ETH_PROVIDER_URI,
"--pre-payment-provider",
"--polygon-endpoint",
TEST_POLYGON_PROVIDER_URI,
)
result = click_runner.invoke(

View File

@ -11,7 +11,6 @@ from nucypher.cli.literature import (
CONFIRM_IPV4_ADDRESS_QUESTION,
REPEAT_FOR_CONFIRMATION,
SELECT_OPERATOR_ACCOUNT,
SELECT_PRE_PAYMENT_NETWORK,
SUCCESSFUL_DESTRUCTION,
)
from nucypher.cli.main import nucypher_cli
@ -58,21 +57,20 @@ def test_interactive_initialize_ursula(click_runner, mocker, tmpdir):
init_args = (
"ursula",
"init",
"--network",
"--domain",
TEMPORARY_DOMAIN,
"--eth-provider",
"--eth-endpoint",
MOCK_ETH_PROVIDER_URI,
"--pre-payment-provider",
"--polygon-endpoint",
MOCK_ETH_PROVIDER_URI,
)
user_input = '0\n' + '0\n' + YES_ENTER + FAKE_PASSWORD_CONFIRMED
result = click_runner.invoke(nucypher_cli, init_args, input=user_input, catch_exceptions=False)
user_input = "0\n" + YES_ENTER + FAKE_PASSWORD_CONFIRMED
result = click_runner.invoke(
nucypher_cli, init_args, input=user_input, catch_exceptions=False
)
assert result.exit_code == 0, result.output
# Select network
assert SELECT_PRE_PAYMENT_NETWORK in result.output
# Select account
assert SELECT_OPERATOR_ACCOUNT in result.output
@ -92,7 +90,7 @@ def test_initialize_custom_configuration_root(
init_args = (
"ursula",
"init",
"--network",
"--domain",
TEMPORARY_DOMAIN,
"--config-root",
str(custom_filepath.absolute()),
@ -100,12 +98,10 @@ def test_initialize_custom_configuration_root(
MOCK_IP_ADDRESS,
"--rest-port",
deploy_port,
"--eth-provider",
"--eth-endpoint",
MOCK_ETH_PROVIDER_URI,
"--pre-payment-provider",
"--polygon-endpoint",
MOCK_ETH_PROVIDER_URI,
"--pre-payment-network",
TEMPORARY_DOMAIN,
"--operator-address",
testerchain.ursulas_accounts[0],
)

View File

@ -48,15 +48,13 @@ def test_ursula_init_with_local_keystore_signer(
"ursula",
"init",
# Layer 1
"--network",
"--domain",
TEMPORARY_DOMAIN,
"--eth-provider",
testerchain.eth_provider_uri,
"--eth-endpoint",
testerchain.endpoint,
# Layer 2
"--pre-payment-network",
TEMPORARY_DOMAIN,
"--pre-payment-provider",
testerchain.eth_provider_uri,
"--polygon-endpoint",
testerchain.endpoint,
"--rest-host",
MOCK_IP_ADDRESS,
"--rest-port",

View File

@ -44,15 +44,13 @@ all_configurations = tuple(
def test_development_character_configurations(
character, configuration, mocker, testerchain
):
mocker.patch.object(
CharacterConfiguration, "DEFAULT_PRE_PAYMENT_NETWORK", TEMPORARY_DOMAIN
)
params = dict(
dev_mode=True,
lonely=True,
domain=TEMPORARY_DOMAIN,
checksum_address=testerchain.unassigned_accounts[0],
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
eth_endpoint=MOCK_ETH_PROVIDER_URI,
polygon_endpoint=MOCK_ETH_PROVIDER_URI,
)
if character is Ursula:
params.update(dict(operator_address=testerchain.unassigned_accounts[0]))
@ -103,7 +101,7 @@ def test_default_character_configuration_preservation(
):
configuration_class.DEFAULT_CONFIG_ROOT = Path("/tmp")
fake_address = "0xdeadbeef"
network = TEMPORARY_DOMAIN
domain = TEMPORARY_DOMAIN
expected_filename = (
f"{configuration_class.NAME}.{configuration_class._CONFIG_FILE_EXTENSION}"
@ -125,22 +123,18 @@ def test_default_character_configuration_preservation(
keystore.signing_public_key = SecretKey.random().public_key()
character_config = configuration_class(
checksum_address=fake_address,
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
domain=network,
eth_endpoint=MOCK_ETH_PROVIDER_URI,
domain=domain,
rest_host=MOCK_IP_ADDRESS,
pre_payment_provider=MOCK_ETH_PROVIDER_URI,
policy_registry=test_registry,
pre_payment_network=TEMPORARY_DOMAIN,
polygon_endpoint=MOCK_ETH_PROVIDER_URI,
keystore=keystore,
)
else:
character_config = configuration_class(
checksum_address=fake_address,
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
domain=network,
pre_payment_network=TEMPORARY_DOMAIN,
policy_registry=test_registry,
eth_endpoint=MOCK_ETH_PROVIDER_URI,
domain=domain,
)
generated_filepath = character_config.generate_filepath()
@ -177,8 +171,8 @@ def test_ursula_development_configuration(testerchain):
checksum_address=testerchain.unassigned_accounts[0],
operator_address=testerchain.unassigned_accounts[1],
domain=TEMPORARY_DOMAIN,
pre_payment_network=TEMPORARY_DOMAIN,
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
eth_endpoint=MOCK_ETH_PROVIDER_URI,
polygon_endpoint=MOCK_ETH_PROVIDER_URI,
)
assert config.is_me is True
assert config.dev_mode is True

View File

@ -14,11 +14,10 @@ def test_alices_powers_are_persistent(ursulas, temp_dir_path, testerchain):
# Create a non-learning AliceConfiguration
config_root = temp_dir_path / 'nucypher-custom-alice-config'
alice_config = AliceConfiguration(
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
eth_endpoint=MOCK_ETH_PROVIDER_URI,
config_root=config_root,
network_middleware=MockRestMiddleware(eth_provider_uri=MOCK_ETH_PROVIDER_URI),
network_middleware=MockRestMiddleware(eth_endpoint=MOCK_ETH_PROVIDER_URI),
domain=TEMPORARY_DOMAIN,
pre_payment_network=TEMPORARY_DOMAIN,
checksum_address=testerchain.alice_account,
start_learning_now=False,
save_metadata=False,
@ -57,8 +56,8 @@ def test_alices_powers_are_persistent(ursulas, temp_dir_path, testerchain):
bob = Bob(
start_learning_now=False,
domain=TEMPORARY_DOMAIN,
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
network_middleware=MockRestMiddleware(eth_provider_uri=MOCK_ETH_PROVIDER_URI),
eth_endpoint=MOCK_ETH_PROVIDER_URI,
network_middleware=MockRestMiddleware(eth_endpoint=MOCK_ETH_PROVIDER_URI),
)
bob_policy = alice.grant(bob, label, threshold=threshold, shares=shares, expiration=policy_end_datetime)
@ -81,7 +80,7 @@ def test_alices_powers_are_persistent(ursulas, temp_dir_path, testerchain):
# A new Alice is restored from the configuration file
new_alice_config = AliceConfiguration.from_configuration_file(
filepath=alice_config_file,
network_middleware=MockRestMiddleware(eth_provider_uri=MOCK_ETH_PROVIDER_URI),
network_middleware=MockRestMiddleware(eth_endpoint=MOCK_ETH_PROVIDER_URI),
start_learning_now=False,
config_root=config_root,
known_nodes=ursulas,
@ -98,9 +97,9 @@ def test_alices_powers_are_persistent(ursulas, temp_dir_path, testerchain):
# Bob's eldest brother, Roberto, appears too
roberto = Bob(
domain=TEMPORARY_DOMAIN,
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
eth_endpoint=MOCK_ETH_PROVIDER_URI,
start_learning_now=False,
network_middleware=MockRestMiddleware(eth_provider_uri=MOCK_ETH_PROVIDER_URI),
network_middleware=MockRestMiddleware(eth_endpoint=MOCK_ETH_PROVIDER_URI),
)
# Alice creates a new policy for Roberto. Note how all the parameters

View File

@ -74,25 +74,27 @@ def test_characters_use_keystore(temp_dir_path, testerchain):
keystore.unlock(password=INSECURE_DEVELOPMENT_PASSWORD)
pre_payment_method = SubscriptionManagerPayment(
eth_provider=MOCK_ETH_PROVIDER_URI, network=TEMPORARY_DOMAIN
blockchain_endpoint=MOCK_ETH_PROVIDER_URI, domain=TEMPORARY_DOMAIN
)
alice = Alice(
start_learning_now=False,
keystore=keystore,
domain=TEMPORARY_DOMAIN,
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
eth_endpoint=MOCK_ETH_PROVIDER_URI,
polygon_endpoint=MOCK_ETH_PROVIDER_URI,
checksum_address=testerchain.alice_account,
pre_payment_method=pre_payment_method,
)
Bob(
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
eth_endpoint=MOCK_ETH_PROVIDER_URI,
start_learning_now=False,
keystore=keystore,
domain=TEMPORARY_DOMAIN,
)
Ursula(
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
eth_endpoint=MOCK_ETH_PROVIDER_URI,
polygon_endpoint=MOCK_ETH_PROVIDER_URI,
start_learning_now=False,
keystore=keystore,
rest_host=LOOPBACK_ADDRESS,
@ -158,7 +160,7 @@ def test_ritualist(temp_dir_path, testerchain, dkg_public_key):
keystore.unlock(password=INSECURE_DEVELOPMENT_PASSWORD)
pre_payment_method = SubscriptionManagerPayment(
eth_provider=MOCK_ETH_PROVIDER_URI, network=TEMPORARY_DOMAIN
blockchain_endpoint=MOCK_ETH_PROVIDER_URI, domain=TEMPORARY_DOMAIN
)
ursula = Ursula(
@ -170,7 +172,8 @@ def test_ritualist(temp_dir_path, testerchain, dkg_public_key):
pre_payment_method=pre_payment_method,
operator_address=testerchain.ursulas_accounts[0],
signer=Web3Signer(testerchain.client),
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
eth_endpoint=MOCK_ETH_PROVIDER_URI,
polygon_endpoint=MOCK_ETH_PROVIDER_URI,
)
ritual_id = 23

View File

@ -35,7 +35,7 @@ class BaseTestNodeStorageBackends:
assert ursula == node_from_storage, "Node storage {} failed".format(node_storage)
pre_payment_method = SubscriptionManagerPayment(
eth_provider=MOCK_ETH_PROVIDER_URI, network=TEMPORARY_DOMAIN
blockchain_endpoint=MOCK_ETH_PROVIDER_URI, domain=TEMPORARY_DOMAIN
)
# Save more nodes
@ -46,7 +46,8 @@ class BaseTestNodeStorageBackends:
rest_port=select_test_port(),
domain=TEMPORARY_DOMAIN,
signer=signer,
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
eth_endpoint=MOCK_ETH_PROVIDER_URI,
polygon_endpoint=MOCK_ETH_PROVIDER_URI,
checksum_address=operator_addresses[i],
operator_address=operator_addresses[i],
pre_payment_method=pre_payment_method,

View File

@ -14,11 +14,14 @@ from nucypher.blockchain.eth.agents import (
TACoChildApplicationAgent,
)
from nucypher.blockchain.eth.clients import EthereumClient
from nucypher.blockchain.eth.domains import (
DomainInfo,
TACoDomain,
)
from nucypher.blockchain.eth.interfaces import (
BlockchainInterface,
BlockchainInterfaceFactory,
)
from nucypher.blockchain.eth.networks import NetworksInventory
from nucypher.blockchain.eth.registry import (
ContractRegistry,
)
@ -35,6 +38,7 @@ from tests.constants import (
MOCK_KEYSTORE_PATH,
NUMBER_OF_MOCK_KEYSTORE_ACCOUNTS,
TESTERCHAIN_CHAIN_ID,
TESTERCHAIN_CHAIN_INFO,
)
from tests.mock.interfaces import MockBlockchain
from tests.mock.io import MockStdinWrapper
@ -132,8 +136,8 @@ def mock_interface(module_mocker):
@pytest.fixture(scope='module')
def test_registry():
with mock_registry_sources():
def test_registry(module_mocker):
with mock_registry_sources(mocker=module_mocker):
mock_source = MockRegistrySource(domain=TEMPORARY_DOMAIN)
registry = ContractRegistry(source=mock_source)
yield registry
@ -278,20 +282,20 @@ def monkeypatch_get_staking_provider_from_operator(monkeymodule):
)
@pytest.fixture(scope="session", autouse=True)
def mock_condition_blockchains(session_mocker):
@pytest.fixture(scope="module", autouse=True)
def mock_condition_blockchains(module_mocker):
"""adds testerchain's chain ID to permitted conditional chains"""
session_mocker.patch.dict(
module_mocker.patch.dict(
"nucypher.policy.conditions.evm._CONDITION_CHAINS",
{TESTERCHAIN_CHAIN_ID: "eth-tester/pyevm"},
)
session_mocker.patch.object(
NetworksInventory, "get_polygon_chain_id", return_value=TESTERCHAIN_CHAIN_ID
test_domain_info = DomainInfo(
TEMPORARY_DOMAIN, TESTERCHAIN_CHAIN_INFO, TESTERCHAIN_CHAIN_INFO
)
session_mocker.patch.object(
NetworksInventory, "get_ethereum_chain_id", return_value=TESTERCHAIN_CHAIN_ID
module_mocker.patch.object(
TACoDomain, "get_domain_info", return_value=test_domain_info
)

View File

@ -2,46 +2,90 @@ from pathlib import Path
import pytest
import tests
from nucypher.acumen.perception import FleetSensor
from nucypher.blockchain.eth.registry import ContractRegistry
from nucypher.characters.lawful import Ursula
from nucypher.config.storages import LocalFileBasedNodeStorage
from nucypher.network.nodes import TEACHER_NODES
from tests.utils.registry import MockRegistrySource
from tests.utils.ursula import make_ursulas
@pytest.mark.skip
def test_learner_learns_about_domains_separately(lonely_ursula_maker, caplog):
hero_learner, other_first_domain_learner = lonely_ursula_maker(
domain="nucypher1.test_suite", quantity=2
)
_nobody = lonely_ursula_maker(domain="nucypher1.test_suite", quantity=1).pop()
other_first_domain_learner.remember_node(_nobody)
@pytest.fixture(scope="module")
def domain_1():
return "domain_uno"
second_domain_learners = lonely_ursula_maker(domain="nucypher2.test_suite", know_each_other=True, quantity=3)
@pytest.fixture(scope="module")
def domain_2():
return "domain_dos"
@pytest.fixture(scope="module")
def test_registry(module_mocker, domain_1, domain_2):
with tests.utils.registry.mock_registry_sources(
mocker=module_mocker, domain_names=[domain_1, domain_2]
):
# doesn't really matter what domain is used here
registry = ContractRegistry(MockRegistrySource(domain=domain_1))
yield registry
@pytest.fixture(scope="module")
def registry_1(domain_1, test_registry):
return ContractRegistry(MockRegistrySource(domain=domain_1))
@pytest.fixture(scope="module")
def registry_2(domain_2, test_registry):
return ContractRegistry(MockRegistrySource(domain=domain_2))
def test_learner_learns_about_domains_separately(
lonely_ursula_maker, domain_1, domain_2, registry_1, registry_2, caplog
):
hero_learner, other_first_domain_learner = lonely_ursula_maker(
domain=domain_1,
registry=registry_1,
quantity=2,
)
_nobody = lonely_ursula_maker(
domain=domain_1, registry=registry_1, quantity=1
).pop()
other_first_domain_learner.remember_node(_nobody, eager=True)
second_domain_learners = lonely_ursula_maker(
domain=domain_2, registry=registry_2, know_each_other=True, quantity=3
)
assert len(hero_learner.known_nodes) == 0
# Learn from a teacher in our domain.
hero_learner.remember_node(other_first_domain_learner)
hero_learner.remember_node(other_first_domain_learner, eager=True)
hero_learner.start_learning_loop(now=True)
hero_learner.learn_from_teacher_node()
hero_learner.learn_from_teacher_node(eager=True)
# All domain 1 nodes
assert len(hero_learner.known_nodes) == 2
# Learn about the second domain.
hero_learner._current_teacher_node = second_domain_learners.pop()
hero_learner.learn_from_teacher_node()
hero_learner.learn_from_teacher_node(eager=True)
# All domain 1 nodes
assert len(hero_learner.known_nodes) == 2
new_first_domain_learner = lonely_ursula_maker(domain="nucypher1.test_suite", quantity=1).pop()
_new_second_domain_learner = lonely_ursula_maker(domain="nucypher2.test_suite", quantity=1).pop()
new_first_domain_learner = lonely_ursula_maker(
domain=domain_1, registry=registry_1, quantity=1
).pop()
_new_second_domain_learner = lonely_ursula_maker(
domain=domain_2, registry=registry_2, quantity=1
).pop()
new_first_domain_learner.remember_node(hero_learner)
new_first_domain_learner.remember_node(hero_learner, eager=True)
new_first_domain_learner.learn_from_teacher_node()
new_first_domain_learner.learn_from_teacher_node(eager=True)
# This node, in the first domain, didn't learn about the second domain.
assert not set(second_domain_learners).intersection(new_first_domain_learner.known_nodes)
@ -52,8 +96,9 @@ def test_learner_learns_about_domains_separately(lonely_ursula_maker, caplog):
assert _nobody in new_first_domain_learner.known_nodes
@pytest.mark.skip
def test_learner_restores_metadata_from_storage(lonely_ursula_maker, tmpdir):
def test_learner_restores_metadata_from_storage(
lonely_ursula_maker, tmpdir, domain_1, domain_2
):
# Create a local file-based node storage
root = tmpdir.mkdir("known_nodes")
metadata = root.mkdir("metadata")
@ -63,20 +108,24 @@ def test_learner_restores_metadata_from_storage(lonely_ursula_maker, tmpdir):
storage_root=Path(root))
# Use the ursula maker with this storage so it's populated with nodes from one domain
_some_ursulas = lonely_ursula_maker(domain="fistro",
node_storage=old_storage,
know_each_other=True,
quantity=3,
save_metadata=True)
_some_ursulas = lonely_ursula_maker(
domain=domain_1,
node_storage=old_storage,
know_each_other=True,
quantity=3,
save_metadata=True,
)
# Create a pair of new learners in a different domain, using the previous storage, and learn from it
new_learners = lonely_ursula_maker(domain="duodenal",
node_storage=old_storage,
quantity=2,
know_each_other=True,
save_metadata=False)
new_learners = lonely_ursula_maker(
domain=domain_2,
node_storage=old_storage,
quantity=2,
know_each_other=True,
save_metadata=False,
)
learner, buddy = new_learners
buddy._Learner__known_nodes = FleetSensor(domain="fistro")
buddy._Learner__known_nodes = FleetSensor(domain=domain_1)
# The learner shouldn't learn about any node from the first domain, since it's different.
learner.learn_from_teacher_node()
@ -88,13 +137,20 @@ def test_learner_restores_metadata_from_storage(lonely_ursula_maker, tmpdir):
assert set(learner.known_nodes) == {buddy}
@pytest.mark.skip
def test_learner_ignores_stored_nodes_from_other_domains(
lonely_ursula_maker, tmpdir, testerchain, ursula_test_config
lonely_ursula_maker,
domain_1,
domain_2,
registry_1,
registry_2,
tmpdir,
testerchain,
ursula_test_config,
):
learner, other_staker = make_ursulas(
ursula_test_config,
domain="call-it-mainnet",
domain=domain_1,
registry=registry_1,
quantity=2,
know_each_other=True,
staking_provider_addresses=testerchain.stake_providers_accounts[:2],
@ -103,7 +159,8 @@ def test_learner_ignores_stored_nodes_from_other_domains(
pest, *other_ursulas_from_the_wrong_side_of_the_tracks = make_ursulas(
ursula_test_config,
domain="i-dunno-testt-maybe",
domain=domain_2,
registry=registry_2,
quantity=5,
know_each_other=True,
staking_provider_addresses=testerchain.stake_providers_accounts[2:],
@ -131,26 +188,33 @@ def test_learner_ignores_stored_nodes_from_other_domains(
assert pest not in other_staker.known_nodes # But not anymore.
@pytest.mark.skip
def test_learner_with_empty_storage_uses_fallback_nodes(lonely_ursula_maker, mocker):
domain = "learner-domain"
mocker.patch.dict(TEACHER_NODES, {domain: ("teacher-uri",)}, clear=True)
def test_learner_with_empty_storage_uses_fallback_nodes(
lonely_ursula_maker, domain_1, mocker
):
mocker.patch.dict(TEACHER_NODES, {domain_1: ("teacher-uri",)}, clear=True)
# Create a learner and a teacher
learner, teacher = lonely_ursula_maker(domain=domain, quantity=2, save_metadata=False)
mocker.patch.object(Ursula, 'from_teacher_uri', return_value=teacher)
learner, teacher = lonely_ursula_maker(
domain=domain_1, quantity=2, save_metadata=False
)
mocker.patch.object(Ursula, "from_teacher_uri", return_value=teacher)
# Since there are no nodes in local node storage, the learner should only learn about the teacher
learner.learn_from_teacher_node()
assert set(learner.known_nodes) == {teacher}
@pytest.mark.skip
def test_learner_uses_both_nodes_from_storage_and_fallback_nodes(
lonely_ursula_maker, tmpdir, mocker, test_registry, ursula_test_config, testerchain
lonely_ursula_maker,
domain_1,
registry_1,
tmpdir,
mocker,
test_registry,
ursula_test_config,
testerchain,
):
domain = "learner-domain"
mocker.patch.dict(TEACHER_NODES, {domain: ("teacher-uri",)}, clear=True)
mocker.patch.dict(TEACHER_NODES, {domain_1: ("teacher-uri",)}, clear=True)
# Create a local file-based node storage
root = tmpdir.mkdir("known_nodes")
@ -163,7 +227,8 @@ def test_learner_uses_both_nodes_from_storage_and_fallback_nodes(
# Create some nodes and persist them to local storage
other_nodes = make_ursulas(
ursula_test_config,
domain=domain,
domain=domain_1,
registry=registry_1,
node_storage=node_storage,
know_each_other=True,
quantity=3,
@ -174,7 +239,8 @@ def test_learner_uses_both_nodes_from_storage_and_fallback_nodes(
# Create a teacher and a learner using existing node storage
learner, teacher = lonely_ursula_maker(
domain=domain,
domain=domain_1,
registry=registry_1,
node_storage=node_storage,
quantity=2,
know_each_other=True,

View File

@ -3,15 +3,18 @@ from functools import partial
import pytest_twisted as pt
from twisted.internet.threads import deferToThread
from nucypher.config.constants import TEMPORARY_DOMAIN
from nucypher.network.middleware import RestMiddleware
from tests.constants import MOCK_ETH_PROVIDER_URI
def test_proper_seed_node_instantiation(lonely_ursula_maker):
_lonely_ursula_maker = partial(lonely_ursula_maker, quantity=1)
firstula = _lonely_ursula_maker(domain="this-is-meaningful-now").pop()
firstula = _lonely_ursula_maker(domain=TEMPORARY_DOMAIN).pop()
firstula_as_seed_node = firstula.seed_node_metadata()
any_other_ursula = _lonely_ursula_maker(seed_nodes=[firstula_as_seed_node], domain="this-is-meaningful-now").pop()
any_other_ursula = _lonely_ursula_maker(
seed_nodes=[firstula_as_seed_node], domain=TEMPORARY_DOMAIN
).pop()
assert not any_other_ursula.known_nodes
any_other_ursula.start_learning_loop(now=True)
@ -33,7 +36,7 @@ def test_get_cert_from_running_seed_node(lonely_ursula_maker):
firstula_as_seed_node = firstula.seed_node_metadata()
any_other_ursula = lonely_ursula_maker(
seed_nodes=[firstula_as_seed_node],
network_middleware=RestMiddleware(eth_provider_uri=MOCK_ETH_PROVIDER_URI),
network_middleware=RestMiddleware(eth_endpoint=MOCK_ETH_PROVIDER_URI),
).pop()
assert not any_other_ursula.known_nodes

View File

@ -20,9 +20,7 @@ def test_alice_can_grant_even_when_the_first_nodes_she_tries_are_down(
label = b"this_is_the_path_to_which_access_is_being_granted"
alice.known_nodes.current_state._nodes = {}
alice.network_middleware = NodeIsDownMiddleware(
eth_provider_uri=MOCK_ETH_PROVIDER_URI
)
alice.network_middleware = NodeIsDownMiddleware(eth_endpoint=MOCK_ETH_PROVIDER_URI)
# OK, her first and only node is down.
down_node = list(ursulas)[0]
@ -78,9 +76,7 @@ def test_alice_can_grant_even_when_the_first_nodes_she_tries_are_down(
def test_node_has_changed_cert(alice, ursulas):
alice.known_nodes.current_state._nodes = {}
alice.network_middleware = NodeIsDownMiddleware(
eth_provider_uri=MOCK_ETH_PROVIDER_URI
)
alice.network_middleware = NodeIsDownMiddleware(eth_endpoint=MOCK_ETH_PROVIDER_URI)
alice.network_middleware.client.certs_are_broken = True
firstula = list(ursulas)[0]

View File

@ -67,7 +67,7 @@ def test_vladimir_illegal_interface_key_does_not_propagate(ursulas):
# This Ursula is totally legit...
ursula_whom_vladimir_will_imitate.verify_node(
MockRestMiddleware(eth_provider_uri=MOCK_ETH_PROVIDER_URI)
MockRestMiddleware(eth_endpoint=MOCK_ETH_PROVIDER_URI)
)
globalLogPublisher.addObserver(warning_trapper)

View File

@ -232,7 +232,7 @@ def test_join(join_worker_pool):
assert t_end - t_start < 3
class TestBatchValueFactory(BatchValueFactory):
class BatchTrackingBatchValueFactory(BatchValueFactory):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.batch_sizes = []
@ -258,7 +258,9 @@ def test_batched_value_generation(join_worker_pool):
seed=123,
)
factory = TestBatchValueFactory(values=list(outcomes), required_successes=10)
factory = BatchTrackingBatchValueFactory(
values=list(outcomes), required_successes=10
)
pool = WorkerPool(
worker,
factory,

View File

@ -70,7 +70,7 @@ def test_ursula_info_metrics_collector(test_registry, ursulas):
@pytest.mark.skipif(condition=(not PROMETHEUS_INSTALLED), reason="prometheus_client is required for test")
def test_blockchain_metrics_collector(testerchain):
collector = BlockchainMetricsCollector(eth_provider_uri=MOCK_ETH_PROVIDER_URI)
collector = BlockchainMetricsCollector(eth_endpoint=MOCK_ETH_PROVIDER_URI)
collector_registry = CollectorRegistry()
prefix = 'test_blockchain_metrics_collector'
@ -96,7 +96,7 @@ def test_staking_provider_metrics_collector(test_registry, staking_providers):
collector = StakingProviderMetricsCollector(
staking_provider_address=staking_provider_address,
contract_registry=test_registry,
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
eth_endpoint=MOCK_ETH_PROVIDER_URI,
)
collector_registry = CollectorRegistry()
prefix = "test_staking_provider_metrics_collector"

View File

@ -22,6 +22,7 @@ from nucypher_core.umbral import SecretKey
from web3 import Web3
from web3.types import Wei
from nucypher.blockchain.eth.domains import LYNX
from nucypher.blockchain.eth.signers import Signer
from nucypher.characters.lawful import Alice, Bob, Ursula
from nucypher.config.characters import AliceConfiguration
@ -53,9 +54,9 @@ except KeyError:
raise RuntimeError(message)
# Alice Configuration
DOMAIN: str = 'mainnet' # tapir
TACO_DOMAIN: str = LYNX.name # mainnet
DEFAULT_SEEDNODE_URIS: List[str] = [
*TEACHER_NODES[DOMAIN],
*TEACHER_NODES[TACO_DOMAIN],
]
INSECURE_PASSWORD: str = "METRICS_INSECURE_DEVELOPMENT_PASSWORD"
TEMP_ALICE_DIR: Path = Path('/', 'tmp', 'grant-metrics')
@ -154,19 +155,19 @@ def make_alice(known_nodes: Optional[Set[Ursula]] = None):
# This is Alice's PRE payment method.
pre_payment_method = SubscriptionManagerPayment(
network='polygon',
eth_provider=POLYGON_PROVIDER_URI
domain=TACO_DOMAIN, blockchain_endpoint=POLYGON_PROVIDER_URI
)
wallet = Signer.from_signer_uri(f'keystore://{SIGNER_URI}')
wallet.unlock_account(account=ALICE_ADDRESS, password=SIGNER_PASSWORD)
alice_config = AliceConfiguration(
eth_provider_uri=ETHEREUM_PROVIDER_URI,
eth_endpoint=ETHEREUM_PROVIDER_URI,
polygon_endpoint=POLYGON_PROVIDER_URI,
checksum_address=ALICE_ADDRESS,
signer_uri=f'keystore://{SIGNER_URI}',
config_root=TEMP_ALICE_DIR,
domain=DOMAIN,
domain=TACO_DOMAIN,
known_nodes=known_nodes,
start_learning_now=False,
learn_on_same_thread=True,
@ -189,14 +190,14 @@ def setup():
GlobalLoggerSettings.set_log_level('info')
def aggregate_nodes(provider_uri: str) -> Tuple[Set[Ursula], Set[Ursula]]:
def aggregate_nodes(eth_endpoint: str) -> Tuple[Set[Ursula], Set[Ursula]]:
"""generates ursulas from URIs used in grant metrics collection"""
seednodes = set()
if DEFAULT_SEEDNODE_URIS:
for uri in DEFAULT_SEEDNODE_URIS:
ursula = Ursula.from_seed_and_stake_info(
seed_uri=uri, provider_uri=provider_uri
seed_uri=uri, eth_endpoint=eth_endpoint
)
seednodes.add(ursula)
@ -204,7 +205,7 @@ def aggregate_nodes(provider_uri: str) -> Tuple[Set[Ursula], Set[Ursula]]:
if HANDPICKED_URSULA_URIS:
for uri in HANDPICKED_URSULA_URIS:
ursula = Ursula.from_seed_and_stake_info(
seed_uri=uri, provider_uri=provider_uri
seed_uri=uri, eth_endpoint=eth_endpoint
)
ursulas.add(ursula)
@ -213,6 +214,6 @@ def aggregate_nodes(provider_uri: str) -> Tuple[Set[Ursula], Set[Ursula]]:
if __name__ == '__main__':
setup()
seednodes, ursulas = aggregate_nodes(provider_uri=ETHEREUM_PROVIDER_URI)
seednodes, ursulas = aggregate_nodes(eth_endpoint=ETHEREUM_PROVIDER_URI)
alice = make_alice(known_nodes=seednodes)
collect(alice=alice, ursulas=ursulas)

View File

@ -1,6 +1,3 @@
from typing import Union
from hexbytes import HexBytes

View File

@ -18,8 +18,8 @@ def pytest_addhooks(pluginmanager):
@pytest.fixture(scope='module')
def test_registry():
with mock_registry_sources():
def test_registry(module_mocker):
with mock_registry_sources(mocker=module_mocker):
source = MockRegistrySource(domain=TEMPORARY_DOMAIN)
yield ContractRegistry(source=source)

View File

@ -22,7 +22,7 @@ def test_actor_without_signing_power_cannot_sign():
crypto_power=cannot_sign,
start_learning_now=False,
domain=TEMPORARY_DOMAIN,
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
eth_endpoint=MOCK_ETH_PROVIDER_URI,
)
# The non-signer's stamp doesn't work for signing...
@ -47,7 +47,7 @@ def test_actor_with_signing_power_can_sign():
is_me=True,
start_learning_now=False,
domain=TEMPORARY_DOMAIN,
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
eth_endpoint=MOCK_ETH_PROVIDER_URI,
)
stamp_of_the_signer = signer.stamp
@ -73,14 +73,14 @@ def test_anybody_can_verify(random_address):
domain=TEMPORARY_DOMAIN,
checksum_address=random_address,
pre_payment_method=FreeReencryptions(),
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
eth_endpoint=MOCK_ETH_PROVIDER_URI,
)
# So, our story is fairly simple: an everyman meets Alice.
somebody = Character(
start_learning_now=False,
domain=TEMPORARY_DOMAIN,
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
eth_endpoint=MOCK_ETH_PROVIDER_URI,
)
# Alice signs a message.

View File

@ -23,7 +23,7 @@ from nucypher.utilities.networking import (
)
from tests.constants import MOCK_ETH_PROVIDER_URI, MOCK_IP_ADDRESS
MOCK_NETWORK = 'holodeck'
MOCK_DOMAIN = "holodeck"
MOCK_PORT = 1111
@ -33,7 +33,7 @@ class Dummy: # Teacher
self.canonical_address = canonical_address
self.checksum_address = to_checksum_address(canonical_address)
self.certificate_filepath = None
self.domain = MOCK_NETWORK
self.domain = MOCK_DOMAIN
class GoodResponse:
status_code = 200
@ -96,7 +96,7 @@ def mock_client(mocker):
@pytest.fixture(autouse=True)
def mock_default_teachers(mocker):
teachers = {MOCK_NETWORK: (f"{MOCK_IP_ADDRESS}:{MOCK_PORT}", )}
teachers = {MOCK_DOMAIN: (f"{MOCK_IP_ADDRESS}:{MOCK_PORT}",)}
mocker.patch.dict(TEACHER_NODES, teachers, clear=True)
@ -106,22 +106,22 @@ def test_get_external_ip_from_centralized_source(mock_requests):
def test_get_external_ip_from_empty_known_nodes(mock_requests):
sensor = FleetSensor(domain=MOCK_NETWORK)
sensor = FleetSensor(domain=MOCK_DOMAIN)
assert len(sensor) == 0
get_external_ip_from_known_nodes(
known_nodes=sensor, provider_uri=MOCK_ETH_PROVIDER_URI
known_nodes=sensor, eth_endpoint=MOCK_ETH_PROVIDER_URI
)
# skipped because there are no known nodes
mock_requests.assert_not_called()
def test_get_external_ip_from_known_nodes_with_one_known_node(mock_requests):
sensor = FleetSensor(domain=MOCK_NETWORK)
sensor = FleetSensor(domain=MOCK_DOMAIN)
sensor.record_node(Dummy(b'deadbeefdeadbeefdead'))
sensor.record_fleet_state()
assert len(sensor) == 1
get_external_ip_from_known_nodes(
known_nodes=sensor, provider_uri=MOCK_ETH_PROVIDER_URI
known_nodes=sensor, eth_endpoint=MOCK_ETH_PROVIDER_URI
)
# skipped because there are too few known nodes
mock_requests.assert_not_called()
@ -130,7 +130,7 @@ def test_get_external_ip_from_known_nodes_with_one_known_node(mock_requests):
def test_get_external_ip_from_known_nodes(mock_client):
# Setup FleetSensor
sensor = FleetSensor(domain=MOCK_NETWORK)
sensor = FleetSensor(domain=MOCK_DOMAIN)
sample_size = 3
sensor.record_node(Dummy(b'deadbeefdeadbeefdead'))
sensor.record_node(Dummy(b'deadllamadeadllamade'))
@ -140,7 +140,7 @@ def test_get_external_ip_from_known_nodes(mock_client):
# First sampled node replies
get_external_ip_from_known_nodes(
known_nodes=sensor, sample_size=sample_size, provider_uri=MOCK_ETH_PROVIDER_URI
known_nodes=sensor, sample_size=sample_size, eth_endpoint=MOCK_ETH_PROVIDER_URI
)
assert mock_client.call_count == 1
mock_client.call_count = 0 # reset
@ -148,7 +148,7 @@ def test_get_external_ip_from_known_nodes(mock_client):
# All sampled nodes dont respond
mock_client.return_value = Dummy.BadResponse
get_external_ip_from_known_nodes(
known_nodes=sensor, sample_size=sample_size, provider_uri=MOCK_ETH_PROVIDER_URI
known_nodes=sensor, sample_size=sample_size, eth_endpoint=MOCK_ETH_PROVIDER_URI
)
assert mock_client.call_count == sample_size
@ -156,7 +156,7 @@ def test_get_external_ip_from_known_nodes(mock_client):
def test_get_external_ip_from_known_nodes_client(mocker, mock_client):
# Setup FleetSensor
sensor = FleetSensor(domain=MOCK_NETWORK)
sensor = FleetSensor(domain=MOCK_DOMAIN)
sample_size = 3
sensor.record_node(Dummy(b'deadbeefdeadbeefdead'))
sensor.record_node(Dummy(b'deadllamadeadllamade'))
@ -166,10 +166,10 @@ def test_get_external_ip_from_known_nodes_client(mocker, mock_client):
# Setup HTTP Client
mocker.patch.object(Ursula, 'from_teacher_uri', return_value=Dummy(b'deadporkdeadporkdead'))
teacher_uri = TEACHER_NODES[MOCK_NETWORK][0]
teacher_uri = TEACHER_NODES[MOCK_DOMAIN][0]
get_external_ip_from_known_nodes(
known_nodes=sensor, sample_size=sample_size, provider_uri=MOCK_ETH_PROVIDER_URI
known_nodes=sensor, sample_size=sample_size, eth_endpoint=MOCK_ETH_PROVIDER_URI
)
assert mock_client.call_count == 1 # first node responded
@ -183,7 +183,7 @@ def test_get_external_ip_default_teacher_unreachable(mocker):
# Default seednode is down
mocker.patch.object(Ursula, "from_teacher_uri", side_effect=error)
ip = get_external_ip_from_default_teacher(
network=MOCK_NETWORK, provider_uri=MOCK_ETH_PROVIDER_URI
domain=MOCK_DOMAIN, eth_endpoint=MOCK_ETH_PROVIDER_URI
)
assert ip is None
@ -191,12 +191,12 @@ def test_get_external_ip_default_teacher_unreachable(mocker):
def test_get_external_ip_from_default_teacher(mocker, mock_client, mock_requests):
mock_client.return_value = Dummy.GoodResponse
teacher_uri = TEACHER_NODES[MOCK_NETWORK][0]
teacher_uri = TEACHER_NODES[MOCK_DOMAIN][0]
mocker.patch.object(Ursula, 'from_teacher_uri', return_value=Dummy(b'deadbeefdeadbeefdead'))
# "Success"
ip = get_external_ip_from_default_teacher(
network=MOCK_NETWORK, provider_uri=MOCK_ETH_PROVIDER_URI
domain=MOCK_DOMAIN, eth_endpoint=MOCK_ETH_PROVIDER_URI
)
assert ip == MOCK_IP_ADDRESS
@ -208,13 +208,13 @@ def test_get_external_ip_from_default_teacher(mocker, mock_client, mock_requests
assert endpoint == f'https://{teacher_uri}/ping'
def test_get_external_ip_default_unknown_network():
def test_get_external_ip_default_unknown_domain():
unknown_domain = 'thisisnotarealdomain'
# Without fleet sensor
with pytest.raises(UnknownIPAddress):
determine_external_ip_address(
network=unknown_domain, provider_uri=MOCK_ETH_PROVIDER_URI
domain=unknown_domain, eth_endpoint=MOCK_ETH_PROVIDER_URI
)
# with fleet sensor
@ -222,8 +222,8 @@ def test_get_external_ip_default_unknown_network():
with pytest.raises(UnknownIPAddress):
determine_external_ip_address(
known_nodes=sensor,
network=unknown_domain,
provider_uri=MOCK_ETH_PROVIDER_URI,
domain=unknown_domain,
eth_endpoint=MOCK_ETH_PROVIDER_URI,
)
@ -232,13 +232,13 @@ def test_get_external_ip_cascade_failure(mocker, mock_requests):
second = mocker.patch('nucypher.utilities.networking.get_external_ip_from_default_teacher', return_value=None)
third = mocker.patch('nucypher.utilities.networking.get_external_ip_from_centralized_source', return_value=None)
sensor = FleetSensor(domain=MOCK_NETWORK)
sensor = FleetSensor(domain=MOCK_DOMAIN)
sensor.record_node(Dummy(b'deadbeefdeadbeefdead'))
sensor.record_fleet_state()
with pytest.raises(UnknownIPAddress, match="External IP address detection failed"):
determine_external_ip_address(
network=MOCK_NETWORK, known_nodes=sensor, provider_uri=MOCK_ETH_PROVIDER_URI
domain=MOCK_DOMAIN, known_nodes=sensor, eth_endpoint=MOCK_ETH_PROVIDER_URI
)
first.assert_called_once()

View File

@ -10,7 +10,7 @@ from tests.mock.coordinator import MockCoordinatorAgent
@pytest.fixture(scope="module")
def agent(mock_contract_agency) -> MockCoordinatorAgent:
coordinator_agent: CoordinatorAgent = mock_contract_agency.get_agent(
CoordinatorAgent, registry=None, provider_uri=MOCK_ETH_PROVIDER_URI
CoordinatorAgent, registry=None, blockchain_endpoint=MOCK_ETH_PROVIDER_URI
)
return coordinator_agent

View File

@ -0,0 +1,86 @@
import pytest
from nucypher.blockchain.eth.domains import (
EthChain,
PolygonChain,
TACoDomain,
)
@pytest.fixture(scope="module")
def test_registry(module_mocker):
# override fixture which mocks SUPPORTED_DOMAIN_NAMES
yield
@pytest.fixture(scope="module", autouse=True)
def mock_condition_blockchains(module_mocker):
# override fixture which mocks get_domain_info
yield
@pytest.mark.parametrize(
"eth_chain_test",
(
(EthChain.MAINNET, "mainnet", 1),
(EthChain.GOERLI, "goerli", 5),
(EthChain.SEPOLIA, "sepolia", 11155111),
),
)
def test_eth_chains(eth_chain_test):
eth_chain, expected_name, expected_id = eth_chain_test
assert eth_chain.name == expected_name
assert eth_chain.id == expected_id
@pytest.mark.parametrize(
"poly_chain_test",
(
(PolygonChain.MAINNET, "polygon", 137),
(PolygonChain.MUMBAI, "mumbai", 80001),
),
)
def test_polygon_chains(poly_chain_test):
eth_chain, expected_name, expected_id = poly_chain_test
assert eth_chain.name == expected_name
assert eth_chain.id == expected_id
@pytest.mark.parametrize(
"taco_domain_test",
(
(TACoDomain.MAINNET, "mainnet", EthChain.MAINNET, PolygonChain.MAINNET),
(TACoDomain.LYNX, "lynx", EthChain.GOERLI, PolygonChain.MUMBAI),
(TACoDomain.TAPIR, "tapir", EthChain.SEPOLIA, PolygonChain.MUMBAI),
),
)
def test_taco_domain_info(taco_domain_test):
(
domain_info,
expected_name,
expected_eth_chain,
expected_polygon_chain,
) = taco_domain_test
assert domain_info.name == expected_name
assert domain_info.eth_chain == expected_eth_chain
assert domain_info.polygon_chain == expected_polygon_chain
assert domain_info.is_testnet == (expected_name != "mainnet")
@pytest.mark.parametrize(
"domain_name_test",
(
("mainnet", TACoDomain.MAINNET),
("lynx", TACoDomain.LYNX),
("tapir", TACoDomain.TAPIR),
),
)
def test_get_domain_info(domain_name_test):
domain_name, expected_domain_info = domain_name_test
assert TACoDomain.get_domain_info(domain_name) == expected_domain_info
def test_get_domain_info_unrecognized_domain_name():
with pytest.raises(TACoDomain.Unrecognized):
TACoDomain.get_domain_info(domain="5am_In_Toronto")

View File

@ -0,0 +1,22 @@
import pytest
from nucypher.blockchain.eth.domains import TACoDomain
from nucypher.network.nodes import TEACHER_NODES
@pytest.fixture(autouse=True)
def mock_teacher_nodes(mocker):
# override fixture which mocks TEACHER_NODES
yield
@pytest.fixture(scope="module")
def test_registry(module_mocker):
# override fixture which mocks SUPPORTED_DOMAIN_NAMES
yield
def test_default_teacher_seednodes_defined():
for domain in TACoDomain.SUPPORTED_DOMAIN_NAMES:
teacher_nodes = TEACHER_NODES[domain]
assert len(teacher_nodes) > 0

View File

@ -1,13 +1,18 @@
import datetime
from unittest.mock import PropertyMock, Mock
from unittest.mock import Mock, PropertyMock
import pytest
from web3 import HTTPProvider, IPCProvider, WebsocketProvider
from nucypher.blockchain.eth.clients import (GanacheClient, GethClient, InfuraClient, PUBLIC_CHAINS,
ParityClient, AlchemyClient)
from nucypher.blockchain.eth.clients import (
AlchemyClient,
GanacheClient,
GethClient,
InfuraClient,
ParityClient,
)
from nucypher.blockchain.eth.interfaces import BlockchainInterface
from nucypher.utilities.networking import LOOPBACK_ADDRESS
@ -139,53 +144,53 @@ class ProviderTypeTestClient(BlockchainInterfaceTestBase):
self.expected_provider_class = expected_provider_class
self.test_provider_to_attach = actual_provider_to_attach
def _attach_eth_provider(self, *args, **kwargs) -> None:
super()._attach_eth_provider(*args, **kwargs)
def _attach_blockchain_provider(self, *args, **kwargs) -> None:
super()._attach_blockchain_provider(*args, **kwargs)
# check type
assert isinstance(self.provider, self.expected_provider_class)
super()._attach_eth_provider(eth_provider=self.test_provider_to_attach)
super()._attach_blockchain_provider(provider=self.test_provider_to_attach)
class InfuraTestClient(BlockchainInterfaceTestBase):
def _attach_eth_provider(self, *args, **kwargs) -> None:
super()._attach_eth_provider(eth_provider=MockInfuraProvider())
def _attach_blockchain_provider(self, *args, **kwargs) -> None:
super()._attach_blockchain_provider(provider=MockInfuraProvider())
class AlchemyTestClient(BlockchainInterfaceTestBase):
def _attach_eth_provider(self, *args, **kwargs) -> None:
super()._attach_eth_provider(eth_provider=MockAlchemyProvider())
def _attach_blockchain_provider(self, *args, **kwargs) -> None:
super()._attach_blockchain_provider(provider=MockAlchemyProvider())
class GethClientTestBlockchain(BlockchainInterfaceTestBase):
def _attach_eth_provider(self, *args, **kwargs) -> None:
super()._attach_eth_provider(eth_provider=MockGethProvider())
def _attach_blockchain_provider(self, *args, **kwargs) -> None:
super()._attach_blockchain_provider(provider=MockGethProvider())
class ParityClientTestInterface(BlockchainInterfaceTestBase):
def _attach_eth_provider(self, *args, **kwargs) -> None:
super()._attach_eth_provider(eth_provider=MockParityProvider())
def _attach_blockchain_provider(self, *args, **kwargs) -> None:
super()._attach_blockchain_provider(provider=MockParityProvider())
class GanacheClientTestInterface(BlockchainInterfaceTestBase):
def _attach_eth_provider(self, *args, **kwargs) -> None:
super()._attach_eth_provider(eth_provider=MockGanacheProvider())
def _attach_blockchain_provider(self, *args, **kwargs) -> None:
super()._attach_blockchain_provider(provider=MockGanacheProvider())
def test_client_no_provider():
with pytest.raises(BlockchainInterface.NoProvider) as e:
with pytest.raises(BlockchainInterface.NoProvider):
interface = BlockchainInterfaceTestBase()
interface.connect()
def test_geth_web3_client():
interface = GethClientTestBlockchain(eth_provider_uri='file:///ipc.geth')
interface = GethClientTestBlockchain(endpoint="file:///ipc.geth")
interface.connect()
assert isinstance(interface.client, GethClient)
@ -199,62 +204,75 @@ def test_geth_web3_client():
def test_autodetect_provider_type_file(tempfile_path):
interface = ProviderTypeTestClient(eth_provider_uri=str(tempfile_path), # existing file for test
expected_provider_class=IPCProvider,
actual_provider_to_attach=MockGethProvider())
interface = ProviderTypeTestClient(
endpoint=str(tempfile_path), # existing file for test
expected_provider_class=IPCProvider,
actual_provider_to_attach=MockGethProvider(),
)
interface.connect()
assert isinstance(interface.client, GethClient)
def test_autodetect_provider_type_file_none_existent():
with pytest.raises(BlockchainInterface.UnsupportedProvider) as e:
interface = BlockchainInterfaceTestBase(eth_provider_uri='/none_existent.ipc.geth')
with pytest.raises(BlockchainInterface.UnsupportedProvider):
interface = BlockchainInterfaceTestBase(endpoint="/none_existent.ipc.geth")
interface.connect()
def test_detect_provider_type_file():
interface = ProviderTypeTestClient(eth_provider_uri='file:///ipc.geth',
expected_provider_class=IPCProvider,
actual_provider_to_attach=MockGethProvider())
interface = ProviderTypeTestClient(
endpoint="file:///ipc.geth",
expected_provider_class=IPCProvider,
actual_provider_to_attach=MockGethProvider(),
)
interface.connect()
assert isinstance(interface.client, GethClient)
def test_detect_provider_type_ipc():
interface = ProviderTypeTestClient(eth_provider_uri='ipc:///ipc.geth',
expected_provider_class=IPCProvider,
actual_provider_to_attach=MockGethProvider())
interface = ProviderTypeTestClient(
endpoint="ipc:///ipc.geth",
expected_provider_class=IPCProvider,
actual_provider_to_attach=MockGethProvider(),
)
interface.connect()
assert isinstance(interface.client, GethClient)
def test_detect_provider_type_http():
interface = ProviderTypeTestClient(eth_provider_uri='http://ganache:8445',
expected_provider_class=HTTPProvider,
actual_provider_to_attach=MockGanacheProvider())
interface = ProviderTypeTestClient(
endpoint="http://ganache:8445",
expected_provider_class=HTTPProvider,
actual_provider_to_attach=MockGanacheProvider(),
)
interface.connect()
assert isinstance(interface.client, GanacheClient)
def test_detect_provider_type_https():
interface = ProviderTypeTestClient(eth_provider_uri='https://ganache:8445',
expected_provider_class=HTTPProvider,
actual_provider_to_attach=MockGanacheProvider())
interface = ProviderTypeTestClient(
endpoint="https://ganache:8445",
expected_provider_class=HTTPProvider,
actual_provider_to_attach=MockGanacheProvider(),
)
interface.connect()
assert isinstance(interface.client, GanacheClient)
def test_detect_provider_type_ws():
interface = ProviderTypeTestClient(eth_provider_uri=f'ws://{LOOPBACK_ADDRESS}:8546',
expected_provider_class=WebsocketProvider,
actual_provider_to_attach=MockWebSocketProvider())
interface = ProviderTypeTestClient(
endpoint=f"ws://{LOOPBACK_ADDRESS}:8546",
expected_provider_class=WebsocketProvider,
actual_provider_to_attach=MockWebSocketProvider(),
)
interface.connect()
assert isinstance(interface.client, GethClient)
def test_infura_web3_client():
interface = InfuraTestClient(eth_provider_uri='wss://:@goerli.infura.io/ws/v3/1234567890987654321abcdef')
interface = InfuraTestClient(
endpoint="wss://:@goerli.infura.io/ws/v3/1234567890987654321abcdef"
)
interface.connect()
assert isinstance(interface.client, InfuraClient)
@ -270,7 +288,9 @@ def test_infura_web3_client():
def test_alchemy_web3_client():
interface = AlchemyTestClient(eth_provider_uri='https://eth-rinkeby.alchemyapi.io/v2/1234567890987654321abcdef')
interface = AlchemyTestClient(
endpoint="https://eth-rinkeby.alchemyapi.io/v2/1234567890987654321abcdef"
)
interface.connect()
assert isinstance(interface.client, AlchemyClient)
@ -282,7 +302,7 @@ def test_alchemy_web3_client():
def test_parity_web3_client():
interface = ParityClientTestInterface(eth_provider_uri='file:///ipc.parity')
interface = ParityClientTestInterface(endpoint="file:///ipc.parity")
interface.connect()
assert isinstance(interface.client, ParityClient)
@ -293,7 +313,7 @@ def test_parity_web3_client():
def test_ganache_web3_client():
interface = GanacheClientTestInterface(eth_provider_uri='http://ganache:8445')
interface = GanacheClientTestInterface(endpoint="http://ganache:8445")
interface.connect()
assert isinstance(interface.client, GanacheClient)

View File

@ -73,18 +73,23 @@ class TesterBlockchain(BlockchainInterface):
__OPERATORS_RANGE = range(NUMBER_OF_URSULAS_IN_BLOCKCHAIN_TESTS)
__ACCOUNT_CACHE = list()
def __init__(self,
test_accounts: int = NUMBER_OF_ETH_TEST_ACCOUNTS,
poa: bool = True,
light: bool = False,
eth_airdrop: bool = False,
*args, **kwargs):
EXPECTED_CONFIRMATION_TIME_IN_SECONDS['free'] = 5 # Just some upper-limit
super().__init__(eth_provider_uri=self.ETH_PROVIDER_URI,
poa=poa,
light=light,
*args, **kwargs)
def __init__(
self,
test_accounts: int = NUMBER_OF_ETH_TEST_ACCOUNTS,
poa: bool = True,
light: bool = False,
eth_airdrop: bool = False,
*args,
**kwargs,
):
EXPECTED_CONFIRMATION_TIME_IN_SECONDS["free"] = 5 # Just some upper-limit
super().__init__(
endpoint=self.ETH_PROVIDER_URI,
poa=poa,
light=light,
*args,
**kwargs,
)
self.log = Logger("test-blockchain")
self.connect()

View File

@ -25,16 +25,16 @@ TEST_CHARACTER_CONFIG_BASE_PARAMS = dict(
def assemble(
checksum_address: str = None,
eth_provider_uri: str = None,
eth_endpoint: str = None,
test_registry: ContractRegistry = None,
known_nodes: List[Ursula] = None,
) -> dict:
"""Assemble a dictionary of keyword arguments to use when constructing a test configuration."""
# Generate runtime config params
runtime_params = dict(
eth_provider_uri=eth_provider_uri,
eth_endpoint=eth_endpoint,
registry=test_registry,
network_middleware=MockRestMiddleware(eth_provider_uri=eth_provider_uri),
network_middleware=MockRestMiddleware(eth_endpoint=eth_endpoint),
known_nodes=known_nodes,
checksum_address=checksum_address,
)
@ -47,30 +47,26 @@ def assemble(
def make_ursula_test_configuration(
operator_address: ChecksumAddress,
rest_port: int = select_test_port(),
pre_payment_provider: str = None,
polygon_endpoint: str = None,
**assemble_kwargs
) -> UrsulaConfiguration:
test_params = assemble(**assemble_kwargs)
ursula_config = UrsulaConfiguration(
**test_params,
rest_port=rest_port,
pre_payment_provider=pre_payment_provider,
pre_payment_network=TEMPORARY_DOMAIN,
polygon_endpoint=polygon_endpoint,
operator_address=operator_address,
policy_registry=test_params["registry"]
)
return ursula_config
def make_alice_test_configuration(
pre_payment_provider: str = None, **assemble_kwargs
polygon_endpoint: str = None, **assemble_kwargs
) -> AliceConfiguration:
test_params = assemble(**assemble_kwargs)
config = AliceConfiguration(
**test_params,
pre_payment_provider=pre_payment_provider,
pre_payment_network=TEMPORARY_DOMAIN,
policy_registry=test_params["registry"]
polygon_endpoint=polygon_endpoint,
)
return config

View File

@ -5,7 +5,7 @@ from pathlib import Path
import requests
from flask import Response
from nucypher_core import MetadataRequest, FleetStateChecksum
from nucypher_core import FleetStateChecksum, MetadataRequest
from nucypher.characters.lawful import Ursula
from nucypher.network.middleware import NucypherMiddlewareClient, RestMiddleware
@ -143,7 +143,7 @@ class NodeIsDownMiddleware(MockRestMiddleware):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.client = _MiddlewareClientWithConnectionProblems(
eth_provider_uri=TEST_ETH_PROVIDER_URI
eth_endpoint=TEST_ETH_PROVIDER_URI
)
def node_is_down(self, node):

View File

@ -5,48 +5,54 @@ from typing import List
from ape.contracts import ContractInstance
from eth_utils import to_checksum_address
from nucypher.blockchain.eth.networks import NetworksInventory
from nucypher.blockchain.eth.domains import (
DomainInfo,
TACoDomain,
)
from nucypher.blockchain.eth.registry import (
RegistryData,
RegistrySource,
RegistrySourceManager,
)
from nucypher.config.constants import TEMPORARY_DOMAIN
from tests.constants import TESTERCHAIN_CHAIN_INFO
@contextmanager
def mock_registry_sources():
# capture the real values
real_networks = NetworksInventory.NETWORKS
real_eth_networks = NetworksInventory.ETH_NETWORKS
real_poly_networks = NetworksInventory.POLY_NETWORKS
real_registry_sources = RegistrySourceManager._FALLBACK_CHAIN
def mock_registry_sources(mocker, domain_names: List[str] = None):
if not domain_names:
domain_names = [TEMPORARY_DOMAIN]
# set the mock values
RegistrySourceManager._FALLBACK_CHAIN = (MockRegistrySource,)
NetworksInventory.NETWORKS = (TEMPORARY_DOMAIN,)
NetworksInventory.ETH_NETWORKS = (TEMPORARY_DOMAIN,)
NetworksInventory.POLY_NETWORKS = (TEMPORARY_DOMAIN,)
supported_domains = []
supported_domain_names = []
for domain_name in domain_names:
test_domain = DomainInfo(
domain_name, TESTERCHAIN_CHAIN_INFO, TESTERCHAIN_CHAIN_INFO
)
supported_domains.append(test_domain)
supported_domain_names.append(domain_name)
mocker.patch.object(TACoDomain, "SUPPORTED_DOMAINS", supported_domains)
mocker.patch.object(TACoDomain, "SUPPORTED_DOMAIN_NAMES", supported_domain_names)
mocker.patch.object(MockRegistrySource, "ALLOWED_DOMAINS", domain_names)
mocker.patch.object(RegistrySourceManager, "_FALLBACK_CHAIN", (MockRegistrySource,))
yield # run the test
# restore the real values
RegistrySourceManager._FALLBACK_CHAIN = real_registry_sources
NetworksInventory.NETWORKS = real_networks
NetworksInventory.ETH_NETWORKS = real_eth_networks
NetworksInventory.POLY_NETWORKS = real_poly_networks
class MockRegistrySource(RegistrySource):
ALLOWED_DOMAINS = [TEMPORARY_DOMAIN]
name = "Mock Registry Source"
is_primary = False
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self.domain != TEMPORARY_DOMAIN:
if self.domain not in self.ALLOWED_DOMAINS:
raise ValueError(
f"Somehow, MockRegistrySource is trying to get a registry for '{self.domain}'. "
f"Only '{TEMPORARY_DOMAIN}' is supported.'"
f"Only '{','.join(self.ALLOWED_DOMAINS)}' are supported.'"
)
@property

View File

@ -10,7 +10,7 @@ from nucypher.characters.lawful import Ursula
from nucypher.config.characters import UrsulaConfiguration
from nucypher.policy.conditions.evm import _CONDITION_CHAINS
from tests.constants import (
NUMBER_OF_URSULAS_IN_DEVELOPMENT_NETWORK,
NUMBER_OF_URSULAS_IN_DEVELOPMENT_DOMAIN,
TESTERCHAIN_CHAIN_ID,
)
@ -68,7 +68,7 @@ def make_ursulas(
ursula_config: UrsulaConfiguration,
staking_provider_addresses: Iterable[str],
operator_addresses: Iterable[str],
quantity: int = NUMBER_OF_URSULAS_IN_DEVELOPMENT_NETWORK,
quantity: int = NUMBER_OF_URSULAS_IN_DEVELOPMENT_DOMAIN,
know_each_other: bool = True,
**ursula_overrides
) -> List[Ursula]:
@ -133,13 +133,15 @@ def mock_permitted_multichain_connections(mocker) -> List[int]:
def setup_multichain_ursulas(chain_ids: List[int], ursulas: List[Ursula]) -> None:
base_uri = "tester://multichain.{}"
base_fallback_uri = "tester://multichain.fallback.{}"
provider_uris = [base_uri.format(i) for i in range(len(chain_ids))]
fallback_provider_uris = [
blockchain_endpoints = [base_uri.format(i) for i in range(len(chain_ids))]
fallback_blockchain_endpoints = [
base_fallback_uri.format(i) for i in range(len(chain_ids))
]
mocked_condition_providers = {
cid: {HTTPProvider(uri), HTTPProvider(furi)}
for cid, uri, furi in zip(chain_ids, provider_uris, fallback_provider_uris)
for cid, uri, furi in zip(
chain_ids, blockchain_endpoints, fallback_blockchain_endpoints
)
}
for ursula in ursulas:
ursula.condition_providers = mocked_condition_providers