Merge pull request #3262 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

View File

@ -178,9 +178,15 @@ man_pages = [
# (source start file, target name, title, author, # (source start file, target name, title, author,
# dir menu entry, description, category) # dir menu entry, description, category)
texinfo_documents = [ texinfo_documents = [
(main_doc, 'NuCypher', 'NuCypher Documentation', (
author, 'NuCypher', 'A proxy re-encryption network to empower privacy in decentralized systems.', main_doc,
'Miscellaneous'), "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.blockchain.eth.signers import InMemorySigner
from nucypher.characters.chaotic import NiceGuyEddie as _Enrico from nucypher.characters.chaotic import NiceGuyEddie as _Enrico
from nucypher.characters.chaotic import ThisBobAlwaysDecrypts from nucypher.characters.chaotic import ThisBobAlwaysDecrypts
@ -8,7 +9,7 @@ THIS_IS_NOT_A_TRINKET = 55 # sometimes called "public key"
signer = InMemorySigner() signer = InMemorySigner()
enrico = _Enrico(encrypting_key=THIS_IS_NOT_A_TRINKET, signer=signer) 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 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`. 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. 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 `TACO_NETWORK` are `lynx`, `tapir` or `mainnet`.
Available options for `L2_NETWORK` are `mumbai` or `mainnet`
Ensure Alice's account has a bit of MATIC on polygon to pay for the policy. 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 import maya
from nucypher.blockchain.eth.domains import TACoDomain
from nucypher.blockchain.eth.signers.base import Signer from nucypher.blockchain.eth.signers.base import Signer
from nucypher.characters.lawful import Alice, Bob from nucypher.characters.lawful import Alice, Bob
from nucypher.characters.lawful import Enrico as Enrico from nucypher.characters.lawful import Enrico as Enrico
@ -40,22 +41,21 @@ except KeyError:
print("\n************** Setup **************\n") print("\n************** Setup **************\n")
########### ##########
# Network # # Domain #
########### ##########
L1_NETWORK = "lynx" TACO_DOMAIN = TACoDomain.LYNX.name
L2_NETWORK = "mumbai"
##################### #####################
# Bob the BUIDLer ## # Bob the BUIDLer ##
##################### #####################
# Then, there was bob. Bob learns about the # Then, there was bob. Bob learns about the
# rest of the network from the seednode. # rest of the domain from the seednode.
bob = Bob( bob = Bob(
domain=L1_NETWORK, domain=TACO_DOMAIN,
eth_provider_uri=L1_PROVIDER, eth_endpoint=L1_PROVIDER,
) )
# Bob puts his public keys somewhere alice can find them. # 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 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 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. # Setup and unlock alice's ethereum wallet.
# WARNING: Never give your mainnet password or mnemonic phrase to anyone. # 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. # This is Alice's PRE payment method.
pre_payment_method = SubscriptionManagerPayment( pre_payment_method = SubscriptionManagerPayment(
network=L2_NETWORK, eth_provider=L2_PROVIDER domain=TACO_DOMAIN, blockchain_endpoint=L2_PROVIDER
) )
# This is Alice. # This is Alice.
alice = Alice( alice = Alice(
checksum_address=ALICE_ADDRESS, checksum_address=ALICE_ADDRESS,
signer=wallet, signer=wallet,
domain=L1_NETWORK, domain=TACO_DOMAIN,
eth_provider_uri=L1_PROVIDER, eth_endpoint=L1_PROVIDER,
polygon_endpoint=L2_PROVIDER,
pre_payment_method=pre_payment_method, 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( remote_bob = Bob.from_public_keys(
encrypting_key=encrypting_key, encrypting_key=encrypting_key,
verifying_key=verifying_key, verifying_key=verifying_key,
eth_provider_uri=L1_PROVIDER, eth_endpoint=L1_PROVIDER,
) )
# These are the policy details. # These are the policy details.

View File

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

View File

@ -9,6 +9,7 @@ import msgpack
from nucypher_core import EncryptedTreasureMap, MessageKit from nucypher_core import EncryptedTreasureMap, MessageKit
from nucypher_core.umbral import PublicKey from nucypher_core.umbral import PublicKey
from nucypher.blockchain.eth.domains import TACoDomain
from nucypher.characters.lawful import Bob from nucypher.characters.lawful import Bob
from nucypher.crypto.keypairs import DecryptingKeypair, SigningKeypair from nucypher.crypto.keypairs import DecryptingKeypair, SigningKeypair
from nucypher.crypto.powers import DecryptingPower, SigningPower from nucypher.crypto.powers import DecryptingPower, SigningPower
@ -27,7 +28,7 @@ except KeyError:
raise RuntimeError("Missing environment variables to run demo.") 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. # To create a Bob, we need the doctor's private keys previously generated.
from doctor_keys import get_doctor_privkeys # noqa: E402 from doctor_keys import get_doctor_privkeys # noqa: E402
@ -43,9 +44,9 @@ power_ups = [enc_power, sig_power]
print("Creating the Doctor ...") print("Creating the Doctor ...")
doctor = Bob( doctor = Bob(
domain=L1_NETWORK, domain=TACO_DOMAIN,
crypto_power_ups=power_ups, crypto_power_ups=power_ups,
eth_provider_uri=L1_PROVIDER, eth_endpoint=L1_PROVIDER,
) )
print("Doctor = ", doctor) 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`. 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. 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 `TACO_NETWORK` are `lynx`, `tapir` or `mainnet`.
Available options for `L2_NETWORK` are `mumbai` or `polygon`
Ensure Alice's account has a bit of MATIC on polygon to pay for the policy. 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_core.ferveo import DkgPublicKey
from nucypher.blockchain.eth.agents import CoordinatorAgent 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.registry import ContractRegistry
from nucypher.blockchain.eth.signers import InMemorySigner from nucypher.blockchain.eth.signers import InMemorySigner
from nucypher.characters.lawful import Bob, Enrico from nucypher.characters.lawful import Bob, Enrico
@ -18,11 +19,10 @@ LOG_LEVEL = "info"
GlobalLoggerSettings.set_log_level(log_level_name=LOG_LEVEL) GlobalLoggerSettings.set_log_level(log_level_name=LOG_LEVEL)
GlobalLoggerSettings.start_console_logging() GlobalLoggerSettings.start_console_logging()
staking_provider_uri = os.environ["DEMO_L1_PROVIDER_URI"] eth_endpoint = os.environ["DEMO_L1_PROVIDER_URI"]
network = "lynx" domain = TACoDomain.LYNX.name
coordinator_provider_uri = os.environ["DEMO_L2_PROVIDER_URI"] polygon_endpoint = os.environ["DEMO_L2_PROVIDER_URI"]
coordinator_network = "mumbai"
############### ###############
# Enrico # Enrico
@ -30,9 +30,13 @@ coordinator_network = "mumbai"
print("--------- Threshold Encryption ---------") print("--------- Threshold Encryption ---------")
registry = ContractRegistry.from_latest_publication(
domain=domain,
)
coordinator_agent = CoordinatorAgent( coordinator_agent = CoordinatorAgent(
provider_uri=coordinator_provider_uri, blockchain_endpoint=polygon_endpoint,
registry=ContractRegistry.from_latest_publication(domain=coordinator_network), registry=registry,
) )
ritual_id = 1 # got this from a side channel ritual_id = 1 # got this from a side channel
ritual = coordinator_agent.get_ritual(ritual_id) ritual = coordinator_agent.get_ritual(ritual_id)
@ -96,11 +100,10 @@ print(f"\nEncrypted message:\n{bytes(threshold_message_kit).hex()}")
print("--------- Threshold Decryption ---------") print("--------- Threshold Decryption ---------")
bob = Bob( bob = Bob(
eth_provider_uri=staking_provider_uri, domain=domain,
domain=network, eth_endpoint=eth_endpoint,
coordinator_provider_uri=coordinator_provider_uri, polygon_endpoint=polygon_endpoint,
coordinator_network=coordinator_network, registry=registry,
registry=ContractRegistry.from_latest_publication(domain=network),
) )
bob.start_learning_loop(now=True) bob.start_learning_loop(now=True)

View File

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

View File

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

View File

@ -81,7 +81,7 @@ class EthereumContractAgent:
def __init__( def __init__(
self, self,
provider_uri: str, blockchain_endpoint: str,
registry: ContractRegistry, registry: ContractRegistry,
contract: Optional[Contract] = None, contract: Optional[Contract] = None,
transaction_gas: Optional[Wei] = None, transaction_gas: Optional[Wei] = None,
@ -91,7 +91,7 @@ class EthereumContractAgent:
self.registry = registry self.registry = registry
self.blockchain = BlockchainInterfaceFactory.get_or_create_interface( self.blockchain = BlockchainInterfaceFactory.get_or_create_interface(
eth_provider_uri=provider_uri endpoint=blockchain_endpoint
) )
if not contract: # Fetch the contract if not contract: # Fetch the contract
@ -106,12 +106,14 @@ class EthereumContractAgent:
transaction_gas = EthereumContractAgent.DEFAULT_TRANSACTION_GAS_LIMITS['default'] transaction_gas = EthereumContractAgent.DEFAULT_TRANSACTION_GAS_LIMITS['default']
self.transaction_gas = transaction_gas self.transaction_gas = transaction_gas
self.log.info("Initialized new {} for {} with {} and {}".format( self.log.info(
"Initialized new {} for {} with {} and {}".format(
self.__class__.__name__, self.__class__.__name__,
self.contract.address, self.contract.address,
self.blockchain.eth_provider_uri, self.blockchain.endpoint,
str(self.registry) str(self.registry),
)) )
)
def __repr__(self) -> str: def __repr__(self) -> str:
class_name = self.__class__.__name__ class_name = self.__class__.__name__
@ -845,15 +847,15 @@ class ContractAgency:
cls, cls,
agent_class: Type[types.Agent], agent_class: Type[types.Agent],
registry: Optional[ContractRegistry], registry: Optional[ContractRegistry],
provider_uri: Optional[str], blockchain_endpoint: Optional[str],
contract_version: Optional[str] = None, contract_version: Optional[str] = None,
) -> types.Agent: ) -> types.Agent:
if not issubclass(agent_class, EthereumContractAgent): if not issubclass(agent_class, EthereumContractAgent):
raise TypeError("Only agent subclasses can be used from the agency.") raise TypeError("Only agent subclasses can be used from the agency.")
if not provider_uri: if not blockchain_endpoint:
raise ValueError( 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: if not registry:
@ -869,7 +871,7 @@ class ContractAgency:
types.Agent, types.Agent,
agent_class( agent_class(
registry=registry, registry=registry,
provider_uri=provider_uri, blockchain_endpoint=blockchain_endpoint,
), ),
) )
cls.__agents[registry_id] = cls.__agents.get(registry_id, dict()) cls.__agents[registry_id] = cls.__agents.get(registry_id, dict())
@ -889,7 +891,7 @@ class ContractAgency:
cls, cls,
contract_name: str, contract_name: str,
registry: ContractRegistry, registry: ContractRegistry,
provider_uri: str, blockchain_endpoint: str,
contract_version: Optional[str] = None, contract_version: Optional[str] = None,
) -> EthereumContractAgent: ) -> EthereumContractAgent:
agent_name: str = cls._contract_name_to_agent_name(name=contract_name) agent_name: str = cls._contract_name_to_agent_name(name=contract_name)
@ -898,7 +900,7 @@ class ContractAgency:
agent: EthereumContractAgent = cls.get_agent( agent: EthereumContractAgent = cls.get_agent(
agent_class=agent_class, agent_class=agent_class,
registry=registry, registry=registry,
provider_uri=provider_uri, blockchain_endpoint=blockchain_endpoint,
contract_version=contract_version contract_version=contract_version
) )
return agent 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 import requests
from constant_sorrow.constants import ( from constant_sorrow.constants import (
INSUFFICIENT_ETH, INSUFFICIENT_FUNDS,
NO_BLOCKCHAIN_CONNECTION, NO_BLOCKCHAIN_CONNECTION,
UNKNOWN_TX_STATUS, UNKNOWN_TX_STATUS,
) )
@ -82,7 +82,7 @@ class BlockchainInterface:
pass pass
REASONS = { REASONS = {
INSUFFICIENT_ETH: 'insufficient funds for gas * price + value', INSUFFICIENT_FUNDS: "insufficient funds for gas * price + value",
} }
class TransactionFailed(InterfaceError): class TransactionFailed(InterfaceError):
@ -100,7 +100,7 @@ class BlockchainInterface:
self.payload = transaction_dict self.payload = transaction_dict
self.contract_function = contract_function self.contract_function = contract_function
self.failures = { 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) self.message = self.failures.get(self.base_message, self.default)
super().__init__(self.message, *args) super().__init__(self.message, *args)
@ -120,7 +120,7 @@ class BlockchainInterface:
return balance return balance
@property @property
def insufficient_eth(self) -> str: def insufficient_funds(self) -> str:
try: try:
transaction_fee = self.payload['gas'] * self.payload['gasPrice'] transaction_fee = self.payload['gas'] * self.payload['gasPrice']
except KeyError: except KeyError:
@ -132,15 +132,16 @@ class BlockchainInterface:
f'but sender only has {prettify_eth_amount(self.get_balance())}.' f'but sender only has {prettify_eth_amount(self.get_balance())}.'
return message return message
def __init__(self, def __init__(
self,
emitter=None, # TODO # 1754 emitter=None, # TODO # 1754
poa: bool = None, poa: bool = None,
light: bool = False, light: bool = False,
eth_provider_uri: str = NO_BLOCKCHAIN_CONNECTION, endpoint: str = NO_BLOCKCHAIN_CONNECTION,
eth_provider: BaseProvider = NO_BLOCKCHAIN_CONNECTION, provider: BaseProvider = NO_BLOCKCHAIN_CONNECTION,
gas_strategy: Optional[Union[str, Callable]] = None, gas_strategy: Optional[Union[str, Callable]] = None,
max_gas_price: Optional[int] = None): max_gas_price: Optional[int] = None,
):
""" """
TODO: #1502 - Move to API docs. TODO: #1502 - Move to API docs.
@ -206,8 +207,8 @@ class BlockchainInterface:
self.log = Logger('Blockchain') self.log = Logger('Blockchain')
self.poa = poa self.poa = poa
self.eth_provider_uri = eth_provider_uri self.endpoint = endpoint
self._eth_provider = eth_provider self._provider = provider
self.w3 = NO_BLOCKCHAIN_CONNECTION self.w3 = NO_BLOCKCHAIN_CONNECTION
self.client = NO_BLOCKCHAIN_CONNECTION self.client = NO_BLOCKCHAIN_CONNECTION
self.is_light = light self.is_light = light
@ -219,7 +220,7 @@ class BlockchainInterface:
self.max_gas_price = max_gas_price self.max_gas_price = max_gas_price
def __repr__(self): 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 return r
def get_blocktime(self): def get_blocktime(self):
@ -292,23 +293,30 @@ class BlockchainInterface:
def connect(self): def connect(self):
eth_provider_uri = self.eth_provider_uri endpoint = self.endpoint
self.log.info(f"Using external Web3 Provider '{self.eth_provider_uri}'") self.log.info(f"Using external Web3 Provider '{self.endpoint}'")
# Attach Provider # Attach Provider
self._attach_eth_provider(eth_provider=self._eth_provider, eth_provider_uri=eth_provider_uri) self._attach_blockchain_provider(
self.log.info("Connecting to {}".format(self.eth_provider_uri)) provider=self._provider,
if self._eth_provider is NO_BLOCKCHAIN_CONNECTION: 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") raise self.NoProvider("There are no configured blockchain providers")
# Connect if not connected # Connect if not connected
try: try:
self.w3 = self.Web3(provider=self._eth_provider) self.w3 = self.Web3(provider=self._provider)
self.client = EthereumClient.from_w3(w3=self.w3) self.client = EthereumClient.from_w3(w3=self.w3)
except requests.ConnectionError: # RPC except requests.ConnectionError: # RPC
raise self.ConnectionFailed(f'Connection Failed - {str(self.eth_provider_uri)} - is RPC enabled?') raise self.ConnectionFailed(
f"Connection Failed - {str(self.endpoint)} - is RPC enabled?"
)
except FileNotFoundError: # IPC File Protocol 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 IPC enabled?"
)
else: else:
self.attach_middleware() self.attach_middleware()
@ -316,20 +324,22 @@ class BlockchainInterface:
@property @property
def provider(self) -> BaseProvider: def provider(self) -> BaseProvider:
return self._eth_provider return self._provider
def _attach_eth_provider(self, def _attach_blockchain_provider(
eth_provider: Optional[BaseProvider] = None, self,
eth_provider_uri: str = None) -> None: provider: Optional[BaseProvider] = None,
endpoint: str = None,
) -> None:
""" """
https://web3py.readthedocs.io/en/latest/providers.html#providers 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.") raise self.NoProvider("No URI or provider instances supplied.")
if eth_provider_uri and not eth_provider: if endpoint and not provider:
uri_breakdown = urlparse(eth_provider_uri) uri_breakdown = urlparse(endpoint)
if uri_breakdown.scheme == 'tester': if uri_breakdown.scheme == 'tester':
providers = { providers = {
@ -352,19 +362,23 @@ class BlockchainInterface:
# auto-detect for file based ipc # auto-detect for file based ipc
if not provider_scheme: if not provider_scheme:
if Path(eth_provider_uri).is_file(): if Path(endpoint).is_file():
# file is available - assume ipc/file scheme # file is available - assume ipc/file scheme
provider_scheme = 'file' provider_scheme = "file"
self.log.info(f"Auto-detected provider scheme as 'file://' for provider {eth_provider_uri}") self.log.info(
f"Auto-detected provider scheme as 'file://' for provider {endpoint}"
)
try: try:
self._eth_provider = providers[provider_scheme](eth_provider_uri) self._provider = providers[provider_scheme](endpoint)
except KeyError: 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: else:
self.eth_provider_uri = eth_provider_uri or NO_BLOCKCHAIN_CONNECTION self.endpoint = endpoint or NO_BLOCKCHAIN_CONNECTION
else: else:
self._eth_provider = eth_provider self._provider = provider
@classmethod @classmethod
def _handle_failed_transaction(cls, def _handle_failed_transaction(cls,
@ -689,11 +703,11 @@ class BlockchainInterfaceFactory:
return cls._instance return cls._instance
@classmethod @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 @classmethod
def register_interface(cls, def register_interface(cls,
@ -702,48 +716,59 @@ class BlockchainInterfaceFactory:
force: bool = False force: bool = False
) -> None: ) -> None:
eth_provider_uri = interface.eth_provider_uri endpoint = interface.endpoint
if (eth_provider_uri in cls._interfaces) and not force: if (endpoint in cls._interfaces) and not force:
raise cls.InterfaceAlreadyInitialized(f"A connection already exists for {eth_provider_uri}. " raise cls.InterfaceAlreadyInitialized(
"Use .get_interface instead.") f"A connection already exists for {endpoint}. "
"Use .get_interface instead."
)
cached = cls.CachedInterface(interface=interface, emitter=emitter) cached = cls.CachedInterface(interface=interface, emitter=emitter)
cls._interfaces[eth_provider_uri] = cached cls._interfaces[endpoint] = cached
@classmethod @classmethod
def initialize_interface(cls, def initialize_interface(
eth_provider_uri: str, cls,
endpoint: str,
emitter=None, emitter=None,
interface_class: Interfaces = None, interface_class: Interfaces = None,
*interface_args, *interface_args,
**interface_kwargs **interface_kwargs,
) -> None: ) -> None:
if not eth_provider_uri: if not endpoint:
# Prevent empty strings and Falsy # 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: if endpoint in cls._interfaces:
raise cls.InterfaceAlreadyInitialized(f"A connection already exists for {eth_provider_uri}. " raise cls.InterfaceAlreadyInitialized(
f"Use .get_interface instead.") f"A connection already exists for {endpoint}. "
f"Use .get_interface instead."
)
# Interface does not exist, initialize a new one. # Interface does not exist, initialize a new one.
if not interface_class: if not interface_class:
interface_class = cls._default_interface_class interface_class = cls._default_interface_class
interface = interface_class(eth_provider_uri=eth_provider_uri, interface = interface_class(
*interface_args, endpoint=endpoint, *interface_args, **interface_kwargs
**interface_kwargs) )
interface.connect() interface.connect()
cls._interfaces[eth_provider_uri] = cls.CachedInterface(interface=interface, emitter=emitter) cls._interfaces[endpoint] = cls.CachedInterface(
interface=interface, emitter=emitter
)
@classmethod @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. # Try to get an existing cached interface.
if eth_provider_uri: if endpoint:
try: try:
cached_interface = cls._interfaces[eth_provider_uri] cached_interface = cls._interfaces[endpoint]
except KeyError: except KeyError:
raise cls.InterfaceNotInitialized(f"There is no connection for {eth_provider_uri}. " raise cls.InterfaceNotInitialized(
f"Call .initialize_connection, then try again.") f"There is no connection for {endpoint}. "
f"Call .initialize_connection, then try again."
)
# Try to use the most recently created interface by default. # Try to use the most recently created interface by default.
else: else:
@ -761,14 +786,16 @@ class BlockchainInterfaceFactory:
return interface return interface
@classmethod @classmethod
def get_or_create_interface(cls, def get_or_create_interface(
eth_provider_uri: str, cls, endpoint: str, *interface_args, **interface_kwargs
*interface_args,
**interface_kwargs
) -> BlockchainInterface: ) -> BlockchainInterface:
try: try:
interface = cls.get_interface(eth_provider_uri=eth_provider_uri) interface = cls.get_interface(endpoint=endpoint)
except (cls.InterfaceNotInitialized, cls.NoRegisteredInterfaces): except (cls.InterfaceNotInitialized, cls.NoRegisteredInterfaces):
cls.initialize_interface(eth_provider_uri=eth_provider_uri, *interface_args, **interface_kwargs) cls.initialize_interface(
interface = cls.get_interface(eth_provider_uri=eth_provider_uri) endpoint=endpoint,
*interface_args,
**interface_kwargs,
)
interface = cls.get_interface(endpoint=endpoint)
return interface 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 pass
def _get_IPC_provider(eth_provider_uri) -> BaseProvider: def _get_IPC_provider(endpoint) -> BaseProvider:
uri_breakdown = urlparse(eth_provider_uri) uri_breakdown = urlparse(endpoint)
from nucypher.blockchain.eth.interfaces import BlockchainInterface from nucypher.blockchain.eth.interfaces import BlockchainInterface
return IPCProvider(ipc_path=uri_breakdown.path, return IPCProvider(ipc_path=uri_breakdown.path,
timeout=BlockchainInterface.TIMEOUT, timeout=BlockchainInterface.TIMEOUT,
request_kwargs={'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 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 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 from web3.auto import w3
# how-automated-detection-works: https://web3py.readthedocs.io/en/latest/providers.html # how-automated-detection-works: https://web3py.readthedocs.io/en/latest/providers.html
connected = w3.isConnected() connected = w3.isConnected()
@ -61,7 +69,7 @@ def _get_ethereum_tester(test_backend: Union[PyEVMBackend, MockBackend]) -> Ethe
return provider return provider
def _get_pyevm_test_provider(eth_provider_uri) -> BaseProvider: def _get_pyevm_test_provider(endpoint) -> BaseProvider:
""" Test provider entry-point""" """ Test provider entry-point"""
# https://github.com/ethereum/eth-tester#pyevm-experimental # https://github.com/ethereum/eth-tester#pyevm-experimental
pyevm_eth_tester = _get_pyevm_test_backend() pyevm_eth_tester = _get_pyevm_test_backend()
@ -69,13 +77,13 @@ def _get_pyevm_test_provider(eth_provider_uri) -> BaseProvider:
return provider 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 # https://github.com/ethereum/eth-tester#mockbackend
mock_backend = MockBackend() mock_backend = MockBackend()
provider = _get_ethereum_tester(test_backend=mock_backend) provider = _get_ethereum_tester(test_backend=mock_backend)
return provider return provider
def _get_tester_ganache(eth_provider_uri=None) -> BaseProvider: def _get_tester_ganache(endpoint=None) -> BaseProvider:
endpoint_uri = eth_provider_uri or 'http://localhost:7545' endpoint_uri = endpoint or "http://localhost:7545"
return HTTPProvider(endpoint_uri=endpoint_uri) return HTTPProvider(endpoint_uri=endpoint_uri)

View File

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

View File

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

View File

@ -20,7 +20,7 @@ class OperatorBondedTracker(SimpleTask):
application_agent = ContractAgency.get_agent( application_agent = ContractAgency.get_agent(
TACoApplicationAgent, TACoApplicationAgent,
registry=self._ursula.registry, 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) # 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( staking_provider_address = application_agent.get_staking_provider_from_operator(

View File

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

View File

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

View File

@ -42,26 +42,25 @@ class Vladimir(Ursula):
raise DevelopmentInstallationRequired( raise DevelopmentInstallationRequired(
importable_name="tests.utils.middleware.EvilMiddleWare" importable_name="tests.utils.middleware.EvilMiddleWare"
) )
blockchain = target_ursula.application_agent.blockchain eth_blockchain = target_ursula.application_agent.blockchain
cls.network_middleware = EvilMiddleWare( cls.network_middleware = EvilMiddleWare(eth_endpoint=eth_blockchain.endpoint)
eth_provider_uri=blockchain.eth_provider_uri
) polygon_blockchain = target_ursula.child_application_agent.blockchain
crypto_power = CryptoPower(power_ups=target_ursula._default_crypto_powerups) 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. # Vladimir does not care about payment.
bogus_pre_payment_method = FreeReencryptions() bogus_pre_payment_method = FreeReencryptions()
bogus_pre_payment_method.provider = Mock() bogus_pre_payment_method.provider = Mock()
bogus_pre_payment_method.agent = Mock() bogus_pre_payment_method.agent = Mock()
bogus_pre_payment_method.network = TEMPORARY_DOMAIN
bogus_pre_payment_method.agent.blockchain.client.chain_id = ( bogus_pre_payment_method.agent.blockchain.client.chain_id = (
blockchain.client.chain_id polygon_blockchain.client.chain_id
) )
mock.patch( mock.patch(
"mock.interfaces.MockBlockchain.client.chain_id", "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( vladimir = cls(
@ -74,8 +73,9 @@ class Vladimir(Ursula):
network_middleware=cls.network_middleware, network_middleware=cls.network_middleware,
checksum_address=cls.fraud_address, checksum_address=cls.fraud_address,
operator_address=cls.fraud_address, operator_address=cls.fraud_address,
signer=Web3Signer(blockchain.client), signer=Web3Signer(eth_blockchain.client),
eth_provider_uri=blockchain.eth_provider_uri, eth_endpoint=eth_blockchain.endpoint,
polygon_endpoint=polygon_blockchain.endpoint,
pre_payment_method=bogus_pre_payment_method, 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( 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: ) -> str:
# From node swarm # From node swarm
try: try:
message = "Detecting external IP address automatically" message = "Detecting external IP address automatically"
emitter.message(message, verbosity=2) 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: except UnknownIPAddress:
if force: if force:
raise raise
@ -157,9 +157,9 @@ def perform_startup_ip_check(emitter: StdoutEmitter, ursula: Ursula, force: bool
""" """
try: try:
external_ip = determine_external_ip_address( external_ip = determine_external_ip_address(
network=ursula.domain, domain=ursula.domain,
known_nodes=ursula.known_nodes, known_nodes=ursula.known_nodes,
provider_uri=ursula.eth_provider_uri, eth_endpoint=ursula.eth_endpoint,
) )
except UnknownIPAddress: except UnknownIPAddress:
message = 'Cannot automatically determine external IP address' message = 'Cannot automatically determine external IP address'

View File

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

View File

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

View File

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

View File

@ -43,9 +43,7 @@ nucypher {init_command}
""" """
SELECT_NETWORK = "Select Network" SELECT_DOMAIN = "Select TACo Domain"
SELECT_PRE_PAYMENT_NETWORK = "Select PRE Payment Network"
NO_CONFIGURATIONS_ON_DISK = "No {name} configurations found. Run 'nucypher {command} init' then try again." 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}." 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" GENERIC_SELECT_ACCOUNT = "Select index of account"

View File

@ -14,7 +14,7 @@ from nucypher.cli.types import (
NETWORK_PORT, NETWORK_PORT,
PRE_PAYMENT_METHOD_CHOICES, PRE_PAYMENT_METHOD_CHOICES,
STAKED_TOKENS_RANGE, STAKED_TOKENS_RANGE,
NuCypherNetworkName, NuCypherDomainName,
) )
from nucypher.utilities.logging import Logger from nucypher.utilities.logging import Logger
@ -79,19 +79,13 @@ option_parameters = click.option(
help="Filepath to a JSON file containing additional parameters", help="Filepath to a JSON file containing additional parameters",
type=EXISTING_READABLE_FILE, type=EXISTING_READABLE_FILE,
) )
option_pre_payment_provider = click.option( option_polygon_endpoint = click.option(
"--pre-payment-provider", "--polygon-endpoint",
"pre_payment_provider", "polygon_endpoint",
help="Connection URL for PRE payment method", help="Connection URL for PRE payment method",
type=click.STRING, type=click.STRING,
required=False, 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( option_pre_payment_method = click.option(
"--pre-payment-method", "--pre-payment-method",
help="PRE payment method name", help="PRE payment method name",
@ -106,11 +100,6 @@ option_registry_filepath = click.option(
help="Custom contract registry filepath", help="Custom contract registry filepath",
type=EXISTING_READABLE_FILE, 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_signer_uri = click.option("--signer", "signer_uri", "-S", default=None, type=str)
option_staking_provider = click.option( option_staking_provider = click.option(
"--staking-provider", "--staking-provider",
@ -180,13 +169,15 @@ def option_message_kit(required: bool = False, multiple: bool = False):
required=required) required=required)
def option_network(required: bool = False, def option_domain(
default: str = None, # NetworksInventory.DEFAULT is not a good global default (2214) required: bool = False,
validate: bool = False): default: str = None, # nucypher.blockchain.eth.domains.DEFAULT.name is not a good global default (#2214)
validate: bool = False,
):
return click.option( return click.option(
'--network', "--domain",
help="NuCypher Network/Domain Name", help="TACo Domain Name",
type=NuCypherNetworkName(validate=validate), type=NuCypherDomainName(validate=validate),
required=required, required=required,
default=default) default=default)
@ -199,9 +190,10 @@ def option_policy_encrypting_key(required: bool = False):
required=required) required=required)
def option_eth_provider_uri(default=None, required: bool = False): def option_eth_endpoint(default=None, required: bool = False):
return click.option( return click.option(
'--eth-provider', 'eth_provider_uri', "--eth-endpoint",
"eth_endpoint",
help="Blockchain provider's URI i.e. 'file:///path/to/geth.ipc'", help="Blockchain provider's URI i.e. 'file:///path/to/geth.ipc'",
type=click.STRING, type=click.STRING,
required=required, 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( application_agent = ContractAgency.get_agent(
TACoApplicationAgent, registry=registry, provider_uri=provider_uri TACoApplicationAgent, registry=registry, blockchain_endpoint=eth_endpoint
) )
blockchain = application_agent.blockchain 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 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): def paint_receipt_summary(
tx_hash = receipt['transactionHash'].hex() emitter,
emitter.echo("OK", color='green', nl=False, bold=True) 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: if transaction_type:
emitter.echo(f" | {transaction_type} | {tx_hash}", color='yellow', nl=False) emitter.echo(f" | {transaction_type} | {tx_hash}", color='yellow', nl=False)
else: 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()}") emitter.echo(f"Block #{receipt['blockNumber']} | {receipt['blockHash'].hex()}")
if not chain_name: 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 chain_name = blockchain.client.chain_name
try: try:
url = etherscan_url(item=tx_hash, network=chain_name) 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 eth_utils import to_checksum_address
from nucypher_core.umbral import PublicKey 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.blockchain.eth.token import TToken
from nucypher.policy.payment import PRE_PAYMENT_METHODS from nucypher.policy.payment import PRE_PAYMENT_METHODS
from nucypher.utilities.networking import InvalidOperatorIP, validate_operator_ip from nucypher.utilities.networking import InvalidOperatorIP, validate_operator_ip
@ -88,21 +88,21 @@ class DecimalRange(DecimalType):
return rv return rv
class NuCypherNetworkName(click.ParamType): class NuCypherDomainName(click.ParamType):
name = 'nucypher_network_name' name = "nucypher_domain_name"
def __init__(self, validate: bool = True): def __init__(self, validate: bool = True):
self.validate = bool(validate) self.validate = bool(validate)
def convert(self, value, param, ctx): def convert(self, value, param, ctx):
if self.validate: if self.validate:
network = str(value).lower() domain = str(value).lower()
if network not in NetworksInventory.ETH_NETWORKS: if domain not in TACoDomain.SUPPORTED_DOMAIN_NAMES:
self.fail( 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: else:
return network return domain
else: else:
return value return value

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -22,15 +22,17 @@ def encode_constructor_arguments(web3: Web3,
return data 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 This may be used to optimize the startup time of some applications by
establishing the connection eagerly. establishing the connection eagerly.
""" """
from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory
if not BlockchainInterfaceFactory.is_interface_initialized(eth_provider_uri=eth_provider_uri): if not BlockchainInterfaceFactory.is_interface_initialized(
BlockchainInterfaceFactory.initialize_interface(eth_provider_uri=eth_provider_uri) endpoint=blockchain_endpoint
interface = BlockchainInterfaceFactory.get_interface(eth_provider_uri=eth_provider_uri) ):
BlockchainInterfaceFactory.initialize_interface(endpoint=blockchain_endpoint)
interface = BlockchainInterfaceFactory.get_interface(endpoint=blockchain_endpoint)
interface.connect() interface.connect()

View File

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

View File

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

View File

@ -157,16 +157,14 @@ def create_metrics_collectors(ursula: "lawful.Ursula") -> List[MetricsCollector]
# Blockchain prometheus # Blockchain prometheus
# TODO possible include information about payment # TODO possible include information about payment
collectors.append( collectors.append(BlockchainMetricsCollector(eth_endpoint=ursula.eth_endpoint))
BlockchainMetricsCollector(eth_provider_uri=ursula.eth_provider_uri)
)
# Staking Provider prometheus # Staking Provider prometheus
collectors.append( collectors.append(
StakingProviderMetricsCollector( StakingProviderMetricsCollector(
staking_provider_address=ursula.checksum_address, staking_provider_address=ursula.checksum_address,
contract_registry=ursula.registry, 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, TACoApplicationAgent,
TACoChildApplicationAgent, TACoChildApplicationAgent,
) )
from nucypher.blockchain.eth.networks import NetworksInventory from nucypher.blockchain.eth.domains import TACoDomain
from nucypher.blockchain.eth.registry import ContractRegistry from nucypher.blockchain.eth.registry import ContractRegistry
from nucypher.utilities.emitters import StdoutEmitter from nucypher.utilities.emitters import StdoutEmitter
from nucypher.utilities.logging import GlobalLoggerSettings from nucypher.utilities.logging import GlobalLoggerSettings
@ -42,71 +42,56 @@ emitter = StdoutEmitter(verbosity=2)
@click.command() @click.command()
@click.option( @click.option(
"--eth-provider", "--domain",
"eth_provider_uri", "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", help="ETH staking network provider URI",
type=click.STRING, type=click.STRING,
required=True, required=True,
) )
@click.option( @click.option(
"--eth-staking-network", "--polygon-endpoint",
"eth_staking_network", "polygon_endpoint",
help="ETH staking network", help="Polygon network provider URI",
type=click.Choice(NetworksInventory.ETH_NETWORKS),
default="lynx",
)
@click.option(
"--coordinator-provider",
"coordinator_provider_uri",
help="Coordinator network provider URI",
type=click.STRING, type=click.STRING,
required=True, required=True,
) )
@click.option(
"--coordinator-network",
"coordinator_network",
help="Coordinator network",
type=click.Choice(NetworksInventory.POLY_NETWORKS),
default="mumbai",
)
def nucypher_agents( def nucypher_agents(
eth_provider_uri, domain,
eth_staking_network, eth_endpoint,
coordinator_provider_uri, polygon_endpoint,
coordinator_network,
): ):
staking_registry = ContractRegistry.from_latest_publication( registry = ContractRegistry.from_latest_publication(domain=domain)
domain=eth_staking_network emitter.echo(f"NOTICE: Connecting to {domain} domain", color="yellow")
)
emitter.echo(f"NOTICE: Connecting to {eth_staking_network} network", color="yellow")
taco_application_agent = ContractAgency.get_agent( taco_application_agent = ContractAgency.get_agent(
agent_class=TACoApplicationAgent, agent_class=TACoApplicationAgent,
registry=staking_registry, registry=registry,
provider_uri=eth_provider_uri, blockchain_endpoint=eth_endpoint,
) # type: TACoApplicationAgent ) # 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( taco_child_application_agent = ContractAgency.get_agent(
agent_class=TACoChildApplicationAgent, agent_class=TACoChildApplicationAgent,
registry=coordinator_network_registry, registry=registry,
provider_uri=coordinator_provider_uri, blockchain_endpoint=polygon_endpoint,
) # type: TACoChildApplicationAgent ) # type: TACoChildApplicationAgent
coordinator_agent = ContractAgency.get_agent( coordinator_agent = ContractAgency.get_agent(
agent_class=CoordinatorAgent, agent_class=CoordinatorAgent,
registry=coordinator_network_registry, registry=registry,
provider_uri=coordinator_provider_uri, blockchain_endpoint=polygon_endpoint,
) # type: CoordinatorAgent ) # type: CoordinatorAgent
subscription_manager_agent = ContractAgency.get_agent( subscription_manager_agent = ContractAgency.get_agent(
agent_class=SubscriptionManagerAgent, agent_class=SubscriptionManagerAgent,
registry=coordinator_network_registry, registry=registry,
provider_uri=coordinator_provider_uri, blockchain_endpoint=polygon_endpoint,
) # type: SubscriptionManagerAgent ) # type: SubscriptionManagerAgent
message = ( message = (

View File

@ -11,6 +11,7 @@ from nucypher.blockchain.eth.agents import (
CoordinatorAgent, CoordinatorAgent,
TACoApplicationAgent, TACoApplicationAgent,
) )
from nucypher.blockchain.eth.domains import TACoDomain
from nucypher.blockchain.eth.registry import ContractRegistry from nucypher.blockchain.eth.registry import ContractRegistry
from nucypher.blockchain.eth.signers import InMemorySigner, Signer from nucypher.blockchain.eth.signers import InMemorySigner, Signer
from nucypher.characters.lawful import Bob, Enrico from nucypher.characters.lawful import Bob, Enrico
@ -43,33 +44,26 @@ def get_transacting_power(signer: Signer):
@click.command() @click.command()
@click.option( @click.option(
"--eth-provider", "--domain",
"eth_provider_uri", "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", help="ETH staking network provider URI",
type=click.STRING, type=click.STRING,
required=True, required=True,
) )
@click.option( @click.option(
"--eth-staking-network", "--polygon-endpoint",
"eth_staking_network", "polygon_endpoint",
help="ETH staking network", help="Polygon network provider URI",
type=click.Choice(["tapir", "lynx"]),
default="lynx",
)
@click.option(
"--coordinator-provider",
"coordinator_provider_uri",
help="Coordinator network provider URI",
type=click.STRING, type=click.STRING,
required=True, required=True,
) )
@click.option(
"--coordinator-network",
"coordinator_network",
help="Coordinator network",
type=click.Choice(["mumbai"]),
default="mumbai",
)
@click.option( @click.option(
"--ritual-id", "--ritual-id",
"ritual_id", "ritual_id",
@ -117,10 +111,9 @@ def get_transacting_power(signer: Signer):
default=False, default=False,
) )
def nucypher_dkg( def nucypher_dkg(
eth_provider_uri, domain,
eth_staking_network, eth_endpoint,
coordinator_provider_uri, polygon_endpoint,
coordinator_network,
ritual_id, ritual_id,
signer_uri, signer_uri,
dkg_size, dkg_size,
@ -161,22 +154,18 @@ def nucypher_dkg(
), ),
) )
coordinator_network_registry = ContractRegistry.from_latest_publication( taco_domain_info = TACoDomain.get_domain_info(domain)
domain=coordinator_network registry = ContractRegistry.from_latest_publication(domain=domain)
)
coordinator_agent = ContractAgency.get_agent( coordinator_agent = ContractAgency.get_agent(
agent_class=CoordinatorAgent, agent_class=CoordinatorAgent,
registry=coordinator_network_registry, registry=registry,
provider_uri=coordinator_provider_uri, blockchain_endpoint=polygon_endpoint,
) # type: CoordinatorAgent ) # type: CoordinatorAgent
staking_network_registry = ContractRegistry.from_latest_publication(
domain=eth_staking_network
)
application_agent = ContractAgency.get_agent( application_agent = ContractAgency.get_agent(
agent_class=TACoApplicationAgent, agent_class=TACoApplicationAgent,
registry=staking_network_registry, registry=registry,
provider_uri=eth_provider_uri, blockchain_endpoint=eth_endpoint,
) # type: TACoApplicationAgent ) # type: TACoApplicationAgent
# #
@ -188,7 +177,7 @@ def nucypher_dkg(
# Get GlobalAllowList contract # Get GlobalAllowList contract
blockchain = coordinator_agent.blockchain blockchain = coordinator_agent.blockchain
allow_list = blockchain.get_contract_by_name( 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("--------- Initiating Ritual ---------", color="yellow")
emitter.echo( 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", color="green",
) )
@ -389,11 +378,10 @@ def nucypher_dkg(
# #
emitter.echo("--------- Threshold Decryption ---------") emitter.echo("--------- Threshold Decryption ---------")
bob = Bob( bob = Bob(
eth_provider_uri=eth_provider_uri, domain=domain,
domain=eth_staking_network, eth_endpoint=eth_endpoint,
registry=staking_network_registry, polygon_endpoint=polygon_endpoint,
coordinator_network=coordinator_network, registry=registry,
coordinator_provider_uri=coordinator_provider_uri,
) )
bob.start_learning_loop(now=True) 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( application_agent_1 = ContractAgency.get_agent(
TACoApplicationAgent, TACoApplicationAgent,
registry=test_registry, registry=test_registry,
provider_uri=TEST_ETH_PROVIDER_URI, blockchain_endpoint=TEST_ETH_PROVIDER_URI,
) )
application_agent_2 = ContractAgency.get_agent( application_agent_2 = ContractAgency.get_agent(
TACoApplicationAgent, TACoApplicationAgent,
registry=test_registry, 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.registry == application_agent_1.registry == test_registry
assert application_agent_2 is application_agent_1 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') @pytest.fixture(scope='module')
def agent(testerchain, test_registry) -> NucypherTokenAgent: def agent(testerchain, test_registry) -> NucypherTokenAgent:
token_agent = ContractAgency.get_agent( 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 return token_agent

View File

@ -30,7 +30,7 @@ def check(policy, bob, ursulas):
def test_grant_subscription_manager(alice, bob, ursulas): def test_grant_subscription_manager(alice, bob, ursulas):
pre_payment_method = SubscriptionManagerPayment( 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 alice.pre_payment_method = pre_payment_method
policy = alice.grant( policy = alice.grant(

View File

@ -137,12 +137,12 @@ def test_invalid_operators_tolerance(
force=True, force=True,
registry=test_registry, registry=test_registry,
network_middleware_client=ursula.network_middleware.client, 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. # In particular, we know that it's bonded to a staker who is really staking.
assert ursula.is_confirmed assert ursula.is_confirmed
assert ursula._staking_provider_is_really_staking( 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. # 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 ... # OK...so...the staker is not staking anymore ...
assert not ursula._staking_provider_is_really_staking( 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) # ... 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, force=True,
registry=test_registry, registry=test_registry,
network_middleware_client=ursula.network_middleware.client, 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) assert len(ursulas) == len(staking_providers)
for ursula in ursulas: for ursula in ursulas:
ursula.validate_operator( 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 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" message = f"Operator {vladimir.operator_address} is not bonded"
with pytest.raises(vladimir.UnbondedOperator, match=message): with pytest.raises(vladimir.UnbondedOperator, match=message):
vladimir.validate_metadata( 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] assert plaintexts == [message]
# Let's consider also that a node may be down when granting # Let's consider also that a node may be down when granting
alice.network_middleware = NodeIsDownMiddleware( alice.network_middleware = NodeIsDownMiddleware(eth_endpoint=MOCK_ETH_PROVIDER_URI)
eth_provider_uri=MOCK_ETH_PROVIDER_URI
)
alice.network_middleware.node_is_down(ursulas[0]) alice.network_middleware.node_is_down(ursulas[0])
with pytest.raises(Policy.NotEnoughUrsulas): with pytest.raises(Policy.NotEnoughUrsulas):

View File

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

View File

@ -73,7 +73,7 @@ def mock_funded_account_password_keystore(
taco_application_agent = ContractAgency.get_agent( taco_application_agent = ContractAgency.get_agent(
TACoApplicationAgent, TACoApplicationAgent,
registry=test_registry, registry=test_registry,
provider_uri=TEST_ETH_PROVIDER_URI, blockchain_endpoint=TEST_ETH_PROVIDER_URI,
) )
taco_application_agent.bond_operator( taco_application_agent.bond_operator(
staking_provider=provider_address, staking_provider=provider_address,
@ -123,17 +123,15 @@ def test_ursula_and_local_keystore_signer_integration(
init_args = ( init_args = (
"ursula", "ursula",
"init", "init",
"--network", "--domain",
TEMPORARY_DOMAIN,
"--pre-payment-network",
TEMPORARY_DOMAIN, TEMPORARY_DOMAIN,
"--operator-address", "--operator-address",
worker_account.address, worker_account.address,
"--config-root", "--config-root",
str(config_root_path.absolute()), str(config_root_path.absolute()),
"--eth-provider", "--eth-endpoint",
TEST_ETH_PROVIDER_URI, TEST_ETH_PROVIDER_URI,
"--pre-payment-provider", "--polygon-endpoint",
TEST_POLYGON_PROVIDER_URI, TEST_POLYGON_PROVIDER_URI,
"--rest-host", "--rest-host",
MOCK_IP_ADDRESS, 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()) @mock.patch('glob.glob', return_value=list())
def test_missing_configuration_file(_default_filepath_mock, click_runner): 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) result = click_runner.invoke(nucypher_cli, cmd_args, catch_exceptions=False)
assert result.exit_code != 0 assert result.exit_code != 0
configuration_type = UrsulaConfiguration.NAME 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 "--dry-run", # Disable twisted reactor in subprocess
"--lonely", # Do not load seednodes "--lonely", # Do not load seednodes
"--prometheus", # Specify collection of prometheus metrics "--prometheus", # Specify collection of prometheus metrics
"--eth-provider", "--eth-endpoint",
TEST_ETH_PROVIDER_URI, TEST_ETH_PROVIDER_URI,
"--pre-payment-provider", "--polygon-endpoint",
TEST_POLYGON_PROVIDER_URI, TEST_POLYGON_PROVIDER_URI,
) )
@ -74,12 +74,10 @@ def test_run_lone_default_development_ursula(click_runner, ursulas, testerchain)
"--lonely", # Do not load seednodes, "--lonely", # Do not load seednodes,
"--operator-address", "--operator-address",
ursulas[0].operator_address, ursulas[0].operator_address,
"--eth-provider", "--eth-endpoint",
TEST_ETH_PROVIDER_URI, TEST_ETH_PROVIDER_URI,
"--pre-payment-provider", "--polygon-endpoint",
TEST_ETH_PROVIDER_URI, TEST_ETH_PROVIDER_URI,
"--pre-payment-network",
TEMPORARY_DOMAIN,
) )
result = yield threads.deferToThread( result = yield threads.deferToThread(
@ -128,12 +126,10 @@ def test_ursula_learns_via_cli(click_runner, ursulas, testerchain):
"--dry-run", # Disable twisted reactor "--dry-run", # Disable twisted reactor
"--operator-address", "--operator-address",
ursulas[0].operator_address, ursulas[0].operator_address,
"--eth-provider", "--eth-endpoint",
TEST_ETH_PROVIDER_URI, TEST_ETH_PROVIDER_URI,
"--pre-payment-provider", "--polygon-endpoint",
TEST_ETH_PROVIDER_URI, TEST_ETH_PROVIDER_URI,
"--pre-payment-network",
TEMPORARY_DOMAIN,
) )
return threads.deferToThread( return threads.deferToThread(
@ -180,15 +176,13 @@ def test_persistent_node_storage_integration(
init_args = ( init_args = (
"ursula", "ursula",
"init", "init",
"--eth-provider", "--eth-endpoint",
TEST_ETH_PROVIDER_URI, TEST_ETH_PROVIDER_URI,
"--pre-payment-provider", "--polygon-endpoint",
TEST_POLYGON_PROVIDER_URI, TEST_POLYGON_PROVIDER_URI,
"--operator-address", "--operator-address",
another_ursula, another_ursula,
"--network", "--domain",
TEMPORARY_DOMAIN,
"--pre-payment-network",
TEMPORARY_DOMAIN, TEMPORARY_DOMAIN,
"--rest-host", "--rest-host",
MOCK_IP_ADDRESS, MOCK_IP_ADDRESS,

View File

@ -52,7 +52,7 @@ def erc20_evm_condition_balanceof(testerchain, test_registry):
token = ContractAgency.get_agent( token = ContractAgency.get_agent(
NucypherTokenAgent, NucypherTokenAgent,
registry=test_registry, registry=test_registry,
provider_uri=TEST_ETH_PROVIDER_URI, blockchain_endpoint=TEST_ETH_PROVIDER_URI,
) )
condition = ContractCondition( condition = ContractCondition(
contract_address=token.contract.address, contract_address=token.contract.address,
@ -115,7 +115,7 @@ def subscription_manager_get_policy_zeroized_policy_struct_condition(
subscription_manager = ContractAgency.get_agent( subscription_manager = ContractAgency.get_agent(
SubscriptionManagerAgent, SubscriptionManagerAgent,
registry=test_registry, registry=test_registry,
provider_uri=TEST_ETH_PROVIDER_URI, blockchain_endpoint=TEST_ETH_PROVIDER_URI,
) )
condition = ContractCondition( condition = ContractCondition(
contract_address=subscription_manager.contract.address, 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( subscription_manager = ContractAgency.get_agent(
SubscriptionManagerAgent, SubscriptionManagerAgent,
registry=test_registry, registry=test_registry,
provider_uri=TEST_ETH_PROVIDER_URI, blockchain_endpoint=TEST_ETH_PROVIDER_URI,
) )
condition = ContractCondition( condition = ContractCondition(
contract_address=subscription_manager.contract.address, contract_address=subscription_manager.contract.address,
@ -157,7 +157,7 @@ def custom_context_variable_erc20_condition(
token = ContractAgency.get_agent( token = ContractAgency.get_agent(
NucypherTokenAgent, NucypherTokenAgent,
registry=test_registry, registry=test_registry,
provider_uri=TEST_ETH_PROVIDER_URI, blockchain_endpoint=TEST_ETH_PROVIDER_URI,
) )
condition = ContractCondition( condition = ContractCondition(
contract_address=token.contract.address, 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( subscription_manager = ContractAgency.get_agent(
SubscriptionManagerAgent, SubscriptionManagerAgent,
registry=test_registry, 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) # 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( subscription_manager = ContractAgency.get_agent(
SubscriptionManagerAgent, SubscriptionManagerAgent,
registry=test_registry, registry=test_registry,
provider_uri=TEST_POLYGON_PROVIDER_URI, blockchain_endpoint=TEST_POLYGON_PROVIDER_URI,
) )
# test "sponsor" index not equal to correct value # test "sponsor" index not equal to correct value

View File

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

View File

@ -1,14 +1,12 @@
import pytest 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 ( from tests.constants import (
DEVELOPMENT_ETH_AIRDROP_AMOUNT, DEVELOPMENT_ETH_AIRDROP_AMOUNT,
NUMBER_OF_ETH_TEST_ACCOUNTS, NUMBER_OF_ETH_TEST_ACCOUNTS,
NUMBER_OF_STAKING_PROVIDERS_IN_BLOCKCHAIN_TESTS, NUMBER_OF_STAKING_PROVIDERS_IN_BLOCKCHAIN_TESTS,
NUMBER_OF_URSULAS_IN_BLOCKCHAIN_TESTS, NUMBER_OF_URSULAS_IN_BLOCKCHAIN_TESTS,
) )
# Prevents TesterBlockchain to be picked up by py.test as a test class # Prevents TesterBlockchain to be picked up by py.test as a test class
from tests.utils.blockchain import TesterBlockchain as _TesterBlockchain from tests.utils.blockchain import TesterBlockchain as _TesterBlockchain
@ -28,7 +26,7 @@ def test_testerchain_creation(testerchain, another_testerchain):
for chain in chains: for chain in chains:
# Ensure we are testing on the correct network... # 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 # ... and that there are already some blocks mined
chain.w3.eth.w3.testing.mine(1) chain.w3.eth.w3.testing.mine(1)

View File

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

View File

@ -7,6 +7,7 @@ from random import SystemRandom
from hexbytes import HexBytes from hexbytes import HexBytes
from web3 import Web3 from web3 import Web3
from nucypher.blockchain.eth.domains import ChainInfo
from nucypher.blockchain.eth.token import NU from nucypher.blockchain.eth.token import NU
from nucypher.config.constants import ( from nucypher.config.constants import (
NUCYPHER_ENVVAR_KEYSTORE_PASSWORD, 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 # 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_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 # Local Signer Keystore
@ -71,6 +72,8 @@ NUMBER_OF_ALLOCATIONS_IN_TESTS = 50 # TODO: Move to constants
TESTERCHAIN_CHAIN_ID = 131277322940537 TESTERCHAIN_CHAIN_ID = 131277322940537
TESTERCHAIN_CHAIN_INFO = ChainInfo(131277322940537, "eth-tester")
# #
# Insecure Secrets # 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.signers.software import KeystoreSigner
from nucypher.blockchain.eth.trackers.dkg import EventScannerTask from nucypher.blockchain.eth.trackers.dkg import EventScannerTask
from nucypher.characters.lawful import Enrico, Ursula from nucypher.characters.lawful import Enrico, Ursula
from nucypher.config.base import CharacterConfiguration
from nucypher.config.characters import ( from nucypher.config.characters import (
AliceConfiguration, AliceConfiguration,
BobConfiguration, BobConfiguration,
@ -130,8 +129,8 @@ def random_address(random_account):
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
def ursula_test_config(test_registry, temp_dir_path, testerchain): def ursula_test_config(test_registry, temp_dir_path, testerchain):
config = make_ursula_test_configuration( config = make_ursula_test_configuration(
eth_provider_uri=TEST_ETH_PROVIDER_URI, eth_endpoint=TEST_ETH_PROVIDER_URI,
pre_payment_provider=TEST_ETH_PROVIDER_URI, polygon_endpoint=TEST_ETH_PROVIDER_URI,
test_registry=test_registry, test_registry=test_registry,
rest_port=select_test_port(), rest_port=select_test_port(),
operator_address=testerchain.ursulas_accounts.pop(), operator_address=testerchain.ursulas_accounts.pop(),
@ -145,8 +144,8 @@ def ursula_test_config(test_registry, temp_dir_path, testerchain):
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
def alice_test_config(ursulas, testerchain, test_registry): def alice_test_config(ursulas, testerchain, test_registry):
config = make_alice_test_configuration( config = make_alice_test_configuration(
eth_provider_uri=TEST_ETH_PROVIDER_URI, eth_endpoint=TEST_ETH_PROVIDER_URI,
pre_payment_provider=TEST_ETH_PROVIDER_URI, polygon_endpoint=TEST_ETH_PROVIDER_URI,
known_nodes=ursulas, known_nodes=ursulas,
checksum_address=testerchain.alice_account, checksum_address=testerchain.alice_account,
test_registry=test_registry, test_registry=test_registry,
@ -157,9 +156,11 @@ def alice_test_config(ursulas, testerchain, test_registry):
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
def bob_test_config(testerchain, test_registry): def bob_test_config(testerchain, test_registry):
config = make_bob_test_configuration(eth_provider_uri=TEST_ETH_PROVIDER_URI, config = make_bob_test_configuration(
eth_endpoint=TEST_ETH_PROVIDER_URI,
test_registry=test_registry, test_registry=test_registry,
checksum_address=testerchain.bob_account) checksum_address=testerchain.bob_account,
)
yield config yield config
config.cleanup() config.cleanup()
@ -197,7 +198,7 @@ def enacted_policy(idle_policy, ursulas):
# cannot set them again # cannot set them again
# deposit = NON_PAYMENT(b"0000000") # deposit = NON_PAYMENT(b"0000000")
# contract_end_datetime = maya.now() + datetime.timedelta(days=5) # 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. # REST call happens here, as does population of TreasureMap.
enacted_policy = idle_policy.enact( enacted_policy = idle_policy.enact(
@ -262,8 +263,7 @@ def alice(alice_test_config, ursulas, testerchain):
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
def bob(bob_test_config, testerchain): def bob(bob_test_config, testerchain):
bob = bob_test_config.produce( bob = bob_test_config.produce(
coordinator_provider_uri=MOCK_ETH_PROVIDER_URI, polygon_endpoint=TEST_ETH_PROVIDER_URI,
coordinator_network=TEMPORARY_DOMAIN,
) )
yield bob yield bob
bob.disenchant() bob.disenchant()
@ -304,8 +304,8 @@ def lonely_ursula_maker(ursula_test_config, testerchain):
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
def mock_registry_sources(): def mock_registry_sources(module_mocker):
with tests.utils.registry.mock_registry_sources(): with tests.utils.registry.mock_registry_sources(module_mocker):
yield yield
@ -323,8 +323,7 @@ def light_ursula(temp_dir_path, random_account, mocker):
KeystoreSigner, "_KeystoreSigner__get_signer", return_value=random_account KeystoreSigner, "_KeystoreSigner__get_signer", return_value=random_account
) )
pre_payment_method = SubscriptionManagerPayment( pre_payment_method = SubscriptionManagerPayment(
eth_provider=MOCK_ETH_PROVIDER_URI, blockchain_endpoint=MOCK_ETH_PROVIDER_URI, domain=TEMPORARY_DOMAIN
network=TEMPORARY_DOMAIN,
) )
mocker.patch.object( mocker.patch.object(
@ -338,7 +337,8 @@ def light_ursula(temp_dir_path, random_account, mocker):
pre_payment_method=pre_payment_method, pre_payment_method=pre_payment_method,
checksum_address=random_account.address, checksum_address=random_account.address,
operator_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), signer=KeystoreSigner(path=temp_dir_path),
) )
return ursula return ursula
@ -434,17 +434,13 @@ def highperf_mocked_alice(
monkeymodule, monkeymodule,
testerchain, testerchain,
): ):
monkeymodule.setattr(
CharacterConfiguration, "DEFAULT_PRE_PAYMENT_NETWORK", TEMPORARY_DOMAIN
)
config = AliceConfiguration( config = AliceConfiguration(
dev_mode=True, dev_mode=True,
domain=TEMPORARY_DOMAIN, domain=TEMPORARY_DOMAIN,
eth_provider_uri=TEST_ETH_PROVIDER_URI, eth_endpoint=TEST_ETH_PROVIDER_URI,
checksum_address=testerchain.alice_account, checksum_address=testerchain.alice_account,
network_middleware=MockRestMiddlewareForLargeFleetTests( network_middleware=MockRestMiddlewareForLargeFleetTests(
eth_provider_uri=TEST_ETH_PROVIDER_URI eth_endpoint=TEST_ETH_PROVIDER_URI
), ),
abort_on_learning_error=True, abort_on_learning_error=True,
save_metadata=False, save_metadata=False,
@ -462,10 +458,10 @@ def highperf_mocked_alice(
def highperf_mocked_bob(fleet_of_highperf_mocked_ursulas): def highperf_mocked_bob(fleet_of_highperf_mocked_ursulas):
config = BobConfiguration( config = BobConfiguration(
dev_mode=True, dev_mode=True,
eth_provider_uri=TEST_ETH_PROVIDER_URI, eth_endpoint=TEST_ETH_PROVIDER_URI,
domain=TEMPORARY_DOMAIN, domain=TEMPORARY_DOMAIN,
network_middleware=MockRestMiddlewareForLargeFleetTests( network_middleware=MockRestMiddlewareForLargeFleetTests(
eth_provider_uri=TEST_ETH_PROVIDER_URI eth_endpoint=TEST_ETH_PROVIDER_URI
), ),
abort_on_learning_error=True, abort_on_learning_error=True,
save_metadata=False, save_metadata=False,
@ -501,9 +497,8 @@ def click_runner():
def nominal_configuration_fields(): def nominal_configuration_fields():
config = UrsulaConfiguration( config = UrsulaConfiguration(
dev_mode=True, dev_mode=True,
pre_payment_network=TEMPORARY_DOMAIN,
domain=TEMPORARY_DOMAIN, domain=TEMPORARY_DOMAIN,
eth_provider_uri=TEST_ETH_PROVIDER_URI, eth_endpoint=TEST_ETH_PROVIDER_URI,
) )
config_fields = config.static_payload() config_fields = config.static_payload()
yield tuple(config_fields.keys()) yield tuple(config_fields.keys())
@ -565,7 +560,7 @@ def basic_auth_file(temp_dir_path):
@pytest.fixture(scope='module') @pytest.fixture(scope='module')
def mock_rest_middleware(): 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) ursulas = list(ursulas)
# All Ursulas are down except for two # All Ursulas are down except for two
bob.network_middleware = NodeIsDownMiddleware( bob.network_middleware = NodeIsDownMiddleware(eth_endpoint=MOCK_ETH_PROVIDER_URI)
eth_provider_uri=MOCK_ETH_PROVIDER_URI
)
for ursula in ursulas[2:]: for ursula in ursulas[2:]:
bob.network_middleware.node_is_down(ursula) 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 nucypher.config.constants import TEMPORARY_DOMAIN
from tests.constants import ( from tests.constants import (
MOCK_ETH_PROVIDER_URI, MOCK_ETH_PROVIDER_URI,
NUMBER_OF_URSULAS_IN_DEVELOPMENT_NETWORK, NUMBER_OF_URSULAS_IN_DEVELOPMENT_DOMAIN,
) )
from tests.utils.middleware import MockRestMiddleware from tests.utils.middleware import MockRestMiddleware
@ -49,8 +49,8 @@ def test_bob_retrieves(alice, ursulas, certificates_tempdir):
bob = Bob( bob = Bob(
domain=TEMPORARY_DOMAIN, domain=TEMPORARY_DOMAIN,
start_learning_now=True, start_learning_now=True,
eth_provider_uri=MOCK_ETH_PROVIDER_URI, eth_endpoint=MOCK_ETH_PROVIDER_URI,
network_middleware=MockRestMiddleware(eth_provider_uri=MOCK_ETH_PROVIDER_URI), network_middleware=MockRestMiddleware(eth_endpoint=MOCK_ETH_PROVIDER_URI),
abort_on_learning_error=True, abort_on_learning_error=True,
known_nodes=a_couple_of_ursulas, 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 # Alice creates a policy granting access to Bob
# Just for fun, let's assume she distributes KFrags among Ursulas unknown 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) label = b'label://' + os.urandom(32)
contract_end_datetime = maya.now() + datetime.timedelta(days=5) contract_end_datetime = maya.now() + datetime.timedelta(days=5)
policy = alice.grant( policy = alice.grant(

View File

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

View File

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

View File

@ -1,24 +1,18 @@
import pytest import pytest
from nucypher.blockchain.eth.networks import NetworksInventory from nucypher.blockchain.eth.domains import TACoDomain
from nucypher.cli.actions.select import select_network from nucypher.cli.actions.select import select_domain
__DOMAINS = TACoDomain.SUPPORTED_DOMAIN_NAMES
@pytest.mark.parametrize( @pytest.mark.parametrize("user_input", range(0, len(__DOMAINS) - 1))
"user_input", range(0, len(NetworksInventory.ETH_NETWORKS) - 1) def test_select_network_cli_action(test_emitter, capsys, mock_stdin, user_input: int):
)
def test_select_network_cli_action_eth(test_emitter, capsys, mock_stdin, user_input):
mock_stdin.line(str(user_input)) mock_stdin.line(str(user_input))
selection = NetworksInventory.ETH_NETWORKS[user_input] selection = __DOMAINS[user_input]
result = select_network(emitter=test_emitter, network_type=NetworksInventory.ETH) result = select_domain(emitter=test_emitter)
assert result == selection assert result == selection
assert result not in NetworksInventory.POLY_NETWORKS
captured = capsys.readouterr() captured = capsys.readouterr()
for name in NetworksInventory.ETH_NETWORKS: for name in __DOMAINS:
assert name in captured.out assert name in captured.out
assert mock_stdin.empty() 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.blockchain.eth.registry import ContractRegistry
from nucypher.cli.main import nucypher_cli 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 ( from nucypher.config.constants import (
NUCYPHER_ENVVAR_KEYSTORE_PASSWORD, NUCYPHER_ENVVAR_KEYSTORE_PASSWORD,
TEMPORARY_DOMAIN, TEMPORARY_DOMAIN,
@ -40,11 +40,11 @@ def test_initialize_via_cli(
init_args = ( init_args = (
command, command,
"init", "init",
"--network", "--domain",
TEMPORARY_DOMAIN, TEMPORARY_DOMAIN,
"--eth-provider", "--eth-endpoint",
MOCK_ETH_PROVIDER_URI, MOCK_ETH_PROVIDER_URI,
"--pre-payment-provider", "--polygon-endpoint",
TEST_ETH_PROVIDER_URI, TEST_ETH_PROVIDER_URI,
"--config-root", "--config-root",
str(custom_filepath.absolute()), str(custom_filepath.absolute()),
@ -82,9 +82,6 @@ def test_reconfigure_via_cli(
monkeypatch.setattr( monkeypatch.setattr(
ContractRegistry, "from_latest_publication", fake_get_latest_registry 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() custom_config_filepath = custom_filepath / config_class.generate_filename()
@ -103,13 +100,18 @@ def test_reconfigure_via_cli(
# Read pre-edit state # Read pre-edit state
config = config_class.from_configuration_file(custom_config_filepath) 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 del config
# Write # Write
view_args = (config_class.CHARACTER_CLASS.__name__.lower(), 'config', view_args = (
'--config-file', str(custom_config_filepath.absolute()), config_class.CHARACTER_CLASS.__name__.lower(),
'--eth-provider', TEST_ETH_PROVIDER_URI) "config",
"--config-file",
str(custom_config_filepath.absolute()),
"--eth-endpoint",
TEST_ETH_PROVIDER_URI,
)
result = click_runner.invoke(nucypher_cli, view_args, env=ENV) result = click_runner.invoke(nucypher_cli, view_args, env=ENV)
assert result.exit_code == 0 assert result.exit_code == 0
@ -121,4 +123,4 @@ def test_reconfigure_via_cli(
assert str(custom_filepath) in result.output assert str(custom_filepath) in result.output
# After editing the fields have been updated # 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 = ( init_args = (
"ursula", "ursula",
"init", "init",
"--eth-provider", "--eth-endpoint",
MOCK_ETH_PROVIDER_URI, MOCK_ETH_PROVIDER_URI,
"--pre-payment-provider", "--polygon-endpoint",
TEST_POLYGON_PROVIDER_URI, TEST_POLYGON_PROVIDER_URI,
"--operator-address", "--operator-address",
another_ursula, another_ursula,
"--network", "--domain",
TEMPORARY_DOMAIN,
"--pre-payment-network",
TEMPORARY_DOMAIN, TEMPORARY_DOMAIN,
"--rest-host", "--rest-host",
MOCK_IP_ADDRESS, MOCK_IP_ADDRESS,
@ -105,13 +103,11 @@ def test_corrupted_configuration(
init_args = ( init_args = (
"ursula", "ursula",
"init", "init",
"--network", "--domain",
TEMPORARY_DOMAIN, TEMPORARY_DOMAIN,
"--pre-payment-network", "--eth-endpoint",
TEMPORARY_DOMAIN,
"--eth-provider",
MOCK_ETH_PROVIDER_URI, MOCK_ETH_PROVIDER_URI,
"--pre-payment-provider", "--polygon-endpoint",
TEST_POLYGON_PROVIDER_URI, TEST_POLYGON_PROVIDER_URI,
"--operator-address", "--operator-address",
another_ursula, another_ursula,

View File

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

View File

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

View File

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

View File

@ -44,15 +44,13 @@ all_configurations = tuple(
def test_development_character_configurations( def test_development_character_configurations(
character, configuration, mocker, testerchain character, configuration, mocker, testerchain
): ):
mocker.patch.object(
CharacterConfiguration, "DEFAULT_PRE_PAYMENT_NETWORK", TEMPORARY_DOMAIN
)
params = dict( params = dict(
dev_mode=True, dev_mode=True,
lonely=True, lonely=True,
domain=TEMPORARY_DOMAIN, domain=TEMPORARY_DOMAIN,
checksum_address=testerchain.unassigned_accounts[0], 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: if character is Ursula:
params.update(dict(operator_address=testerchain.unassigned_accounts[0])) 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") configuration_class.DEFAULT_CONFIG_ROOT = Path("/tmp")
fake_address = "0xdeadbeef" fake_address = "0xdeadbeef"
network = TEMPORARY_DOMAIN domain = TEMPORARY_DOMAIN
expected_filename = ( expected_filename = (
f"{configuration_class.NAME}.{configuration_class._CONFIG_FILE_EXTENSION}" 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() keystore.signing_public_key = SecretKey.random().public_key()
character_config = configuration_class( character_config = configuration_class(
checksum_address=fake_address, checksum_address=fake_address,
eth_provider_uri=MOCK_ETH_PROVIDER_URI, eth_endpoint=MOCK_ETH_PROVIDER_URI,
domain=network, domain=domain,
rest_host=MOCK_IP_ADDRESS, rest_host=MOCK_IP_ADDRESS,
pre_payment_provider=MOCK_ETH_PROVIDER_URI, polygon_endpoint=MOCK_ETH_PROVIDER_URI,
policy_registry=test_registry,
pre_payment_network=TEMPORARY_DOMAIN,
keystore=keystore, keystore=keystore,
) )
else: else:
character_config = configuration_class( character_config = configuration_class(
checksum_address=fake_address, checksum_address=fake_address,
eth_provider_uri=MOCK_ETH_PROVIDER_URI, eth_endpoint=MOCK_ETH_PROVIDER_URI,
domain=network, domain=domain,
pre_payment_network=TEMPORARY_DOMAIN,
policy_registry=test_registry,
) )
generated_filepath = character_config.generate_filepath() generated_filepath = character_config.generate_filepath()
@ -177,8 +171,8 @@ def test_ursula_development_configuration(testerchain):
checksum_address=testerchain.unassigned_accounts[0], checksum_address=testerchain.unassigned_accounts[0],
operator_address=testerchain.unassigned_accounts[1], operator_address=testerchain.unassigned_accounts[1],
domain=TEMPORARY_DOMAIN, domain=TEMPORARY_DOMAIN,
pre_payment_network=TEMPORARY_DOMAIN, eth_endpoint=MOCK_ETH_PROVIDER_URI,
eth_provider_uri=MOCK_ETH_PROVIDER_URI, polygon_endpoint=MOCK_ETH_PROVIDER_URI,
) )
assert config.is_me is True assert config.is_me is True
assert config.dev_mode 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 # Create a non-learning AliceConfiguration
config_root = temp_dir_path / 'nucypher-custom-alice-config' config_root = temp_dir_path / 'nucypher-custom-alice-config'
alice_config = AliceConfiguration( alice_config = AliceConfiguration(
eth_provider_uri=MOCK_ETH_PROVIDER_URI, eth_endpoint=MOCK_ETH_PROVIDER_URI,
config_root=config_root, 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, domain=TEMPORARY_DOMAIN,
pre_payment_network=TEMPORARY_DOMAIN,
checksum_address=testerchain.alice_account, checksum_address=testerchain.alice_account,
start_learning_now=False, start_learning_now=False,
save_metadata=False, save_metadata=False,
@ -57,8 +56,8 @@ def test_alices_powers_are_persistent(ursulas, temp_dir_path, testerchain):
bob = Bob( bob = Bob(
start_learning_now=False, start_learning_now=False,
domain=TEMPORARY_DOMAIN, domain=TEMPORARY_DOMAIN,
eth_provider_uri=MOCK_ETH_PROVIDER_URI, eth_endpoint=MOCK_ETH_PROVIDER_URI,
network_middleware=MockRestMiddleware(eth_provider_uri=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) 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 # A new Alice is restored from the configuration file
new_alice_config = AliceConfiguration.from_configuration_file( new_alice_config = AliceConfiguration.from_configuration_file(
filepath=alice_config_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, start_learning_now=False,
config_root=config_root, config_root=config_root,
known_nodes=ursulas, 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 # Bob's eldest brother, Roberto, appears too
roberto = Bob( roberto = Bob(
domain=TEMPORARY_DOMAIN, domain=TEMPORARY_DOMAIN,
eth_provider_uri=MOCK_ETH_PROVIDER_URI, eth_endpoint=MOCK_ETH_PROVIDER_URI,
start_learning_now=False, 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 # 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) keystore.unlock(password=INSECURE_DEVELOPMENT_PASSWORD)
pre_payment_method = SubscriptionManagerPayment( pre_payment_method = SubscriptionManagerPayment(
eth_provider=MOCK_ETH_PROVIDER_URI, network=TEMPORARY_DOMAIN blockchain_endpoint=MOCK_ETH_PROVIDER_URI, domain=TEMPORARY_DOMAIN
) )
alice = Alice( alice = Alice(
start_learning_now=False, start_learning_now=False,
keystore=keystore, keystore=keystore,
domain=TEMPORARY_DOMAIN, 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, checksum_address=testerchain.alice_account,
pre_payment_method=pre_payment_method, pre_payment_method=pre_payment_method,
) )
Bob( Bob(
eth_provider_uri=MOCK_ETH_PROVIDER_URI, eth_endpoint=MOCK_ETH_PROVIDER_URI,
start_learning_now=False, start_learning_now=False,
keystore=keystore, keystore=keystore,
domain=TEMPORARY_DOMAIN, domain=TEMPORARY_DOMAIN,
) )
Ursula( Ursula(
eth_provider_uri=MOCK_ETH_PROVIDER_URI, eth_endpoint=MOCK_ETH_PROVIDER_URI,
polygon_endpoint=MOCK_ETH_PROVIDER_URI,
start_learning_now=False, start_learning_now=False,
keystore=keystore, keystore=keystore,
rest_host=LOOPBACK_ADDRESS, rest_host=LOOPBACK_ADDRESS,
@ -158,7 +160,7 @@ def test_ritualist(temp_dir_path, testerchain, dkg_public_key):
keystore.unlock(password=INSECURE_DEVELOPMENT_PASSWORD) keystore.unlock(password=INSECURE_DEVELOPMENT_PASSWORD)
pre_payment_method = SubscriptionManagerPayment( pre_payment_method = SubscriptionManagerPayment(
eth_provider=MOCK_ETH_PROVIDER_URI, network=TEMPORARY_DOMAIN blockchain_endpoint=MOCK_ETH_PROVIDER_URI, domain=TEMPORARY_DOMAIN
) )
ursula = Ursula( ursula = Ursula(
@ -170,7 +172,8 @@ def test_ritualist(temp_dir_path, testerchain, dkg_public_key):
pre_payment_method=pre_payment_method, pre_payment_method=pre_payment_method,
operator_address=testerchain.ursulas_accounts[0], operator_address=testerchain.ursulas_accounts[0],
signer=Web3Signer(testerchain.client), 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 ritual_id = 23

View File

@ -35,7 +35,7 @@ class BaseTestNodeStorageBackends:
assert ursula == node_from_storage, "Node storage {} failed".format(node_storage) assert ursula == node_from_storage, "Node storage {} failed".format(node_storage)
pre_payment_method = SubscriptionManagerPayment( 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 # Save more nodes
@ -46,7 +46,8 @@ class BaseTestNodeStorageBackends:
rest_port=select_test_port(), rest_port=select_test_port(),
domain=TEMPORARY_DOMAIN, domain=TEMPORARY_DOMAIN,
signer=signer, 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], checksum_address=operator_addresses[i],
operator_address=operator_addresses[i], operator_address=operator_addresses[i],
pre_payment_method=pre_payment_method, pre_payment_method=pre_payment_method,

View File

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

View File

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

View File

@ -3,15 +3,18 @@ from functools import partial
import pytest_twisted as pt import pytest_twisted as pt
from twisted.internet.threads import deferToThread from twisted.internet.threads import deferToThread
from nucypher.config.constants import TEMPORARY_DOMAIN
from nucypher.network.middleware import RestMiddleware from nucypher.network.middleware import RestMiddleware
from tests.constants import MOCK_ETH_PROVIDER_URI from tests.constants import MOCK_ETH_PROVIDER_URI
def test_proper_seed_node_instantiation(lonely_ursula_maker): def test_proper_seed_node_instantiation(lonely_ursula_maker):
_lonely_ursula_maker = partial(lonely_ursula_maker, quantity=1) _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() 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 assert not any_other_ursula.known_nodes
any_other_ursula.start_learning_loop(now=True) 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() firstula_as_seed_node = firstula.seed_node_metadata()
any_other_ursula = lonely_ursula_maker( any_other_ursula = lonely_ursula_maker(
seed_nodes=[firstula_as_seed_node], 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() ).pop()
assert not any_other_ursula.known_nodes 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" label = b"this_is_the_path_to_which_access_is_being_granted"
alice.known_nodes.current_state._nodes = {} alice.known_nodes.current_state._nodes = {}
alice.network_middleware = NodeIsDownMiddleware( alice.network_middleware = NodeIsDownMiddleware(eth_endpoint=MOCK_ETH_PROVIDER_URI)
eth_provider_uri=MOCK_ETH_PROVIDER_URI
)
# OK, her first and only node is down. # OK, her first and only node is down.
down_node = list(ursulas)[0] 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): def test_node_has_changed_cert(alice, ursulas):
alice.known_nodes.current_state._nodes = {} alice.known_nodes.current_state._nodes = {}
alice.network_middleware = NodeIsDownMiddleware( alice.network_middleware = NodeIsDownMiddleware(eth_endpoint=MOCK_ETH_PROVIDER_URI)
eth_provider_uri=MOCK_ETH_PROVIDER_URI
)
alice.network_middleware.client.certs_are_broken = True alice.network_middleware.client.certs_are_broken = True
firstula = list(ursulas)[0] 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... # This Ursula is totally legit...
ursula_whom_vladimir_will_imitate.verify_node( 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) globalLogPublisher.addObserver(warning_trapper)

View File

@ -232,7 +232,7 @@ def test_join(join_worker_pool):
assert t_end - t_start < 3 assert t_end - t_start < 3
class TestBatchValueFactory(BatchValueFactory): class BatchTrackingBatchValueFactory(BatchValueFactory):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.batch_sizes = [] self.batch_sizes = []
@ -258,7 +258,9 @@ def test_batched_value_generation(join_worker_pool):
seed=123, seed=123,
) )
factory = TestBatchValueFactory(values=list(outcomes), required_successes=10) factory = BatchTrackingBatchValueFactory(
values=list(outcomes), required_successes=10
)
pool = WorkerPool( pool = WorkerPool(
worker, worker,
factory, 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") @pytest.mark.skipif(condition=(not PROMETHEUS_INSTALLED), reason="prometheus_client is required for test")
def test_blockchain_metrics_collector(testerchain): 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() collector_registry = CollectorRegistry()
prefix = 'test_blockchain_metrics_collector' prefix = 'test_blockchain_metrics_collector'
@ -96,7 +96,7 @@ def test_staking_provider_metrics_collector(test_registry, staking_providers):
collector = StakingProviderMetricsCollector( collector = StakingProviderMetricsCollector(
staking_provider_address=staking_provider_address, staking_provider_address=staking_provider_address,
contract_registry=test_registry, contract_registry=test_registry,
eth_provider_uri=MOCK_ETH_PROVIDER_URI, eth_endpoint=MOCK_ETH_PROVIDER_URI,
) )
collector_registry = CollectorRegistry() collector_registry = CollectorRegistry()
prefix = "test_staking_provider_metrics_collector" prefix = "test_staking_provider_metrics_collector"

View File

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

View File

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

View File

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

View File

@ -22,7 +22,7 @@ def test_actor_without_signing_power_cannot_sign():
crypto_power=cannot_sign, crypto_power=cannot_sign,
start_learning_now=False, start_learning_now=False,
domain=TEMPORARY_DOMAIN, 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... # 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, is_me=True,
start_learning_now=False, start_learning_now=False,
domain=TEMPORARY_DOMAIN, domain=TEMPORARY_DOMAIN,
eth_provider_uri=MOCK_ETH_PROVIDER_URI, eth_endpoint=MOCK_ETH_PROVIDER_URI,
) )
stamp_of_the_signer = signer.stamp stamp_of_the_signer = signer.stamp
@ -73,14 +73,14 @@ def test_anybody_can_verify(random_address):
domain=TEMPORARY_DOMAIN, domain=TEMPORARY_DOMAIN,
checksum_address=random_address, checksum_address=random_address,
pre_payment_method=FreeReencryptions(), 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. # So, our story is fairly simple: an everyman meets Alice.
somebody = Character( somebody = Character(
start_learning_now=False, start_learning_now=False,
domain=TEMPORARY_DOMAIN, domain=TEMPORARY_DOMAIN,
eth_provider_uri=MOCK_ETH_PROVIDER_URI, eth_endpoint=MOCK_ETH_PROVIDER_URI,
) )
# Alice signs a message. # 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 from tests.constants import MOCK_ETH_PROVIDER_URI, MOCK_IP_ADDRESS
MOCK_NETWORK = 'holodeck' MOCK_DOMAIN = "holodeck"
MOCK_PORT = 1111 MOCK_PORT = 1111
@ -33,7 +33,7 @@ class Dummy: # Teacher
self.canonical_address = canonical_address self.canonical_address = canonical_address
self.checksum_address = to_checksum_address(canonical_address) self.checksum_address = to_checksum_address(canonical_address)
self.certificate_filepath = None self.certificate_filepath = None
self.domain = MOCK_NETWORK self.domain = MOCK_DOMAIN
class GoodResponse: class GoodResponse:
status_code = 200 status_code = 200
@ -96,7 +96,7 @@ def mock_client(mocker):
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
def mock_default_teachers(mocker): 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) 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): 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 assert len(sensor) == 0
get_external_ip_from_known_nodes( 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 # skipped because there are no known nodes
mock_requests.assert_not_called() mock_requests.assert_not_called()
def test_get_external_ip_from_known_nodes_with_one_known_node(mock_requests): 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_node(Dummy(b'deadbeefdeadbeefdead'))
sensor.record_fleet_state() sensor.record_fleet_state()
assert len(sensor) == 1 assert len(sensor) == 1
get_external_ip_from_known_nodes( 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 # skipped because there are too few known nodes
mock_requests.assert_not_called() 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): def test_get_external_ip_from_known_nodes(mock_client):
# Setup FleetSensor # Setup FleetSensor
sensor = FleetSensor(domain=MOCK_NETWORK) sensor = FleetSensor(domain=MOCK_DOMAIN)
sample_size = 3 sample_size = 3
sensor.record_node(Dummy(b'deadbeefdeadbeefdead')) sensor.record_node(Dummy(b'deadbeefdeadbeefdead'))
sensor.record_node(Dummy(b'deadllamadeadllamade')) sensor.record_node(Dummy(b'deadllamadeadllamade'))
@ -140,7 +140,7 @@ def test_get_external_ip_from_known_nodes(mock_client):
# First sampled node replies # First sampled node replies
get_external_ip_from_known_nodes( 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 assert mock_client.call_count == 1
mock_client.call_count = 0 # reset 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 # All sampled nodes dont respond
mock_client.return_value = Dummy.BadResponse mock_client.return_value = Dummy.BadResponse
get_external_ip_from_known_nodes( 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 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): def test_get_external_ip_from_known_nodes_client(mocker, mock_client):
# Setup FleetSensor # Setup FleetSensor
sensor = FleetSensor(domain=MOCK_NETWORK) sensor = FleetSensor(domain=MOCK_DOMAIN)
sample_size = 3 sample_size = 3
sensor.record_node(Dummy(b'deadbeefdeadbeefdead')) sensor.record_node(Dummy(b'deadbeefdeadbeefdead'))
sensor.record_node(Dummy(b'deadllamadeadllamade')) 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 # Setup HTTP Client
mocker.patch.object(Ursula, 'from_teacher_uri', return_value=Dummy(b'deadporkdeadporkdead')) 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( 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 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 # Default seednode is down
mocker.patch.object(Ursula, "from_teacher_uri", side_effect=error) mocker.patch.object(Ursula, "from_teacher_uri", side_effect=error)
ip = get_external_ip_from_default_teacher( 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 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): def test_get_external_ip_from_default_teacher(mocker, mock_client, mock_requests):
mock_client.return_value = Dummy.GoodResponse 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')) mocker.patch.object(Ursula, 'from_teacher_uri', return_value=Dummy(b'deadbeefdeadbeefdead'))
# "Success" # "Success"
ip = get_external_ip_from_default_teacher( 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 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' 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' unknown_domain = 'thisisnotarealdomain'
# Without fleet sensor # Without fleet sensor
with pytest.raises(UnknownIPAddress): with pytest.raises(UnknownIPAddress):
determine_external_ip_address( 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 # with fleet sensor
@ -222,8 +222,8 @@ def test_get_external_ip_default_unknown_network():
with pytest.raises(UnknownIPAddress): with pytest.raises(UnknownIPAddress):
determine_external_ip_address( determine_external_ip_address(
known_nodes=sensor, known_nodes=sensor,
network=unknown_domain, domain=unknown_domain,
provider_uri=MOCK_ETH_PROVIDER_URI, 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) 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) 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_node(Dummy(b'deadbeefdeadbeefdead'))
sensor.record_fleet_state() sensor.record_fleet_state()
with pytest.raises(UnknownIPAddress, match="External IP address detection failed"): with pytest.raises(UnknownIPAddress, match="External IP address detection failed"):
determine_external_ip_address( 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() first.assert_called_once()

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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