mirror of https://github.com/nucypher/nucypher.git
Merge pull request #3262 from derekpierre/network-entrenchment
TACo Domain Entrenchment/Assocationpull/3275/head
commit
c93fc2884f
docs/source
examples
newsfragments
nucypher
blockchain/eth
characters
cli
network
policy
utilities
scripts/hooks
tests
integration
metrics
mock
|
@ -178,9 +178,15 @@ man_pages = [
|
|||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
(main_doc, 'NuCypher', 'NuCypher Documentation',
|
||||
author, 'NuCypher', 'A proxy re-encryption network to empower privacy in decentralized systems.',
|
||||
'Miscellaneous'),
|
||||
(
|
||||
main_doc,
|
||||
"NuCypher",
|
||||
"NuCypher Documentation",
|
||||
author,
|
||||
"NuCypher",
|
||||
"A threshold access control application to empower privacy in decentralized systems.",
|
||||
"Miscellaneous",
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from nucypher.blockchain.eth.domains import TACoDomain
|
||||
from nucypher.blockchain.eth.signers import InMemorySigner
|
||||
from nucypher.characters.chaotic import NiceGuyEddie as _Enrico
|
||||
from nucypher.characters.chaotic import ThisBobAlwaysDecrypts
|
||||
|
@ -8,7 +9,7 @@ THIS_IS_NOT_A_TRINKET = 55 # sometimes called "public key"
|
|||
|
||||
signer = InMemorySigner()
|
||||
enrico = _Enrico(encrypting_key=THIS_IS_NOT_A_TRINKET, signer=signer)
|
||||
bob = ThisBobAlwaysDecrypts(domain="lynx", eth_provider_uri="Nowhere")
|
||||
bob = ThisBobAlwaysDecrypts(domain=TACoDomain.LYNX.name, eth_endpoint="Nowhere")
|
||||
|
||||
ANYTHING_CAN_BE_PASSED_AS_RITUAL_ID = 55
|
||||
|
||||
|
|
|
@ -20,8 +20,7 @@ and adding your provider and wallet details. To set the variables in your curre
|
|||
Optionally, you can change the network the demo is running on by changing the value of `L1_NETWORK` and `L2_NETWORK`.
|
||||
If you change these values be sure to also change `L1_PROVIDER_URI` and `L2_PROVIDER_URI` accordingly.
|
||||
|
||||
Available options for `L1_NETWORK` are `tapir` or `mainnet`.
|
||||
Available options for `L2_NETWORK` are `mumbai` or `mainnet`
|
||||
Available options for `TACO_NETWORK` are `lynx`, `tapir` or `mainnet`.
|
||||
|
||||
Ensure Alice's account has a bit of MATIC on polygon to pay for the policy.
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ from pathlib import Path
|
|||
|
||||
import maya
|
||||
|
||||
from nucypher.blockchain.eth.domains import TACoDomain
|
||||
from nucypher.blockchain.eth.signers.base import Signer
|
||||
from nucypher.characters.lawful import Alice, Bob
|
||||
from nucypher.characters.lawful import Enrico as Enrico
|
||||
|
@ -40,22 +41,21 @@ except KeyError:
|
|||
|
||||
print("\n************** Setup **************\n")
|
||||
|
||||
###########
|
||||
# Network #
|
||||
###########
|
||||
##########
|
||||
# Domain #
|
||||
##########
|
||||
|
||||
L1_NETWORK = "lynx"
|
||||
L2_NETWORK = "mumbai"
|
||||
TACO_DOMAIN = TACoDomain.LYNX.name
|
||||
|
||||
#####################
|
||||
# Bob the BUIDLer ##
|
||||
#####################
|
||||
|
||||
# Then, there was bob. Bob learns about the
|
||||
# rest of the network from the seednode.
|
||||
# rest of the domain from the seednode.
|
||||
bob = Bob(
|
||||
domain=L1_NETWORK,
|
||||
eth_provider_uri=L1_PROVIDER,
|
||||
domain=TACO_DOMAIN,
|
||||
eth_endpoint=L1_PROVIDER,
|
||||
)
|
||||
|
||||
# Bob puts his public keys somewhere alice can find them.
|
||||
|
@ -67,9 +67,9 @@ encrypting_key = bob.public_keys(DecryptingPower)
|
|||
######################################
|
||||
|
||||
# Connect to the ethereum provider.
|
||||
connect_web3_provider(eth_provider_uri=L1_PROVIDER)
|
||||
connect_web3_provider(blockchain_endpoint=L1_PROVIDER)
|
||||
# Connect to the layer 2 provider.
|
||||
connect_web3_provider(eth_provider_uri=L2_PROVIDER)
|
||||
connect_web3_provider(blockchain_endpoint=L2_PROVIDER)
|
||||
|
||||
# Setup and unlock alice's ethereum wallet.
|
||||
# WARNING: Never give your mainnet password or mnemonic phrase to anyone.
|
||||
|
@ -82,15 +82,16 @@ wallet.unlock_account(account=ALICE_ADDRESS, password=password)
|
|||
|
||||
# This is Alice's PRE payment method.
|
||||
pre_payment_method = SubscriptionManagerPayment(
|
||||
network=L2_NETWORK, eth_provider=L2_PROVIDER
|
||||
domain=TACO_DOMAIN, blockchain_endpoint=L2_PROVIDER
|
||||
)
|
||||
|
||||
# This is Alice.
|
||||
alice = Alice(
|
||||
checksum_address=ALICE_ADDRESS,
|
||||
signer=wallet,
|
||||
domain=L1_NETWORK,
|
||||
eth_provider_uri=L1_PROVIDER,
|
||||
domain=TACO_DOMAIN,
|
||||
eth_endpoint=L1_PROVIDER,
|
||||
polygon_endpoint=L2_PROVIDER,
|
||||
pre_payment_method=pre_payment_method,
|
||||
)
|
||||
|
||||
|
@ -111,7 +112,7 @@ policy_public_key = alice.get_policy_encrypting_key_from_label(label)
|
|||
remote_bob = Bob.from_public_keys(
|
||||
encrypting_key=encrypting_key,
|
||||
verifying_key=verifying_key,
|
||||
eth_provider_uri=L1_PROVIDER,
|
||||
eth_endpoint=L1_PROVIDER,
|
||||
)
|
||||
|
||||
# These are the policy details.
|
||||
|
|
|
@ -24,6 +24,7 @@ from pathlib import Path
|
|||
|
||||
import maya
|
||||
|
||||
from nucypher.blockchain.eth.domains import TACoDomain
|
||||
from nucypher.blockchain.eth.signers import Signer
|
||||
from nucypher.characters.lawful import Alice, Bob
|
||||
from nucypher.policy.payment import SubscriptionManagerPayment
|
||||
|
@ -57,16 +58,19 @@ try:
|
|||
except KeyError:
|
||||
raise RuntimeError("Missing environment variables to run demo.")
|
||||
|
||||
L1_NETWORK = "lynx"
|
||||
L2_NETWORK = "mumbai"
|
||||
TACO_DOMAIN = TACoDomain.LYNX.name
|
||||
|
||||
|
||||
#######################################
|
||||
# Alicia, the Authority of the Policy #
|
||||
#######################################
|
||||
|
||||
connect_web3_provider(eth_provider_uri=L1_PROVIDER) # Connect to the ethereum provider.
|
||||
connect_web3_provider(eth_provider_uri=L2_PROVIDER) # Connect to the layer 2 provider.
|
||||
connect_web3_provider(
|
||||
blockchain_endpoint=L1_PROVIDER
|
||||
) # Connect to the ethereum provider.
|
||||
connect_web3_provider(
|
||||
blockchain_endpoint=L2_PROVIDER
|
||||
) # Connect to the layer 2 provider.
|
||||
|
||||
|
||||
# Setup and unlock alice's ethereum wallet.
|
||||
|
@ -80,15 +84,16 @@ wallet.unlock_account(account=ALICE_ADDRESS, password=password)
|
|||
|
||||
# This is Alice's PRE payment method.
|
||||
pre_payment_method = SubscriptionManagerPayment(
|
||||
network=L2_NETWORK, eth_provider=L2_PROVIDER
|
||||
domain=TACO_DOMAIN, blockchain_endpoint=L2_PROVIDER
|
||||
)
|
||||
|
||||
# This is Alicia.
|
||||
alicia = Alice(
|
||||
checksum_address=ALICE_ADDRESS,
|
||||
signer=wallet,
|
||||
domain=L1_NETWORK,
|
||||
eth_provider_uri=L1_PROVIDER,
|
||||
domain=TACO_DOMAIN,
|
||||
eth_endpoint=L1_PROVIDER,
|
||||
polygon_endpoint=L2_PROVIDER,
|
||||
pre_payment_method=pre_payment_method,
|
||||
)
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import msgpack
|
|||
from nucypher_core import EncryptedTreasureMap, MessageKit
|
||||
from nucypher_core.umbral import PublicKey
|
||||
|
||||
from nucypher.blockchain.eth.domains import TACoDomain
|
||||
from nucypher.characters.lawful import Bob
|
||||
from nucypher.crypto.keypairs import DecryptingKeypair, SigningKeypair
|
||||
from nucypher.crypto.powers import DecryptingPower, SigningPower
|
||||
|
@ -27,7 +28,7 @@ except KeyError:
|
|||
raise RuntimeError("Missing environment variables to run demo.")
|
||||
|
||||
|
||||
L1_NETWORK = "lynx"
|
||||
TACO_DOMAIN = TACoDomain.LYNX.name
|
||||
|
||||
# To create a Bob, we need the doctor's private keys previously generated.
|
||||
from doctor_keys import get_doctor_privkeys # noqa: E402
|
||||
|
@ -43,9 +44,9 @@ power_ups = [enc_power, sig_power]
|
|||
print("Creating the Doctor ...")
|
||||
|
||||
doctor = Bob(
|
||||
domain=L1_NETWORK,
|
||||
domain=TACO_DOMAIN,
|
||||
crypto_power_ups=power_ups,
|
||||
eth_provider_uri=L1_PROVIDER,
|
||||
eth_endpoint=L1_PROVIDER,
|
||||
)
|
||||
|
||||
print("Doctor = ", doctor)
|
||||
|
|
|
@ -47,8 +47,7 @@ and adding your provider and wallet details. To set the variables in your curre
|
|||
Optionally, you can change the network the demo is running on by changing the value of `L1_NETWORK` and `L2_NETWORK`.
|
||||
If you change these values be sure to also change `L1_PROVIDER_URI` and `L2_PROVIDER_URI` accordingly.
|
||||
|
||||
Available options for `L1_NETOWRK` are `tapir` or `mainnet`.
|
||||
Available options for `L2_NETWORK` are `mumbai` or `polygon`
|
||||
Available options for `TACO_NETWORK` are `lynx`, `tapir` or `mainnet`.
|
||||
|
||||
Ensure Alice's account has a bit of MATIC on polygon to pay for the policy.
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ import os
|
|||
from nucypher_core.ferveo import DkgPublicKey
|
||||
|
||||
from nucypher.blockchain.eth.agents import CoordinatorAgent
|
||||
from nucypher.blockchain.eth.domains import TACoDomain
|
||||
from nucypher.blockchain.eth.registry import ContractRegistry
|
||||
from nucypher.blockchain.eth.signers import InMemorySigner
|
||||
from nucypher.characters.lawful import Bob, Enrico
|
||||
|
@ -18,11 +19,10 @@ LOG_LEVEL = "info"
|
|||
GlobalLoggerSettings.set_log_level(log_level_name=LOG_LEVEL)
|
||||
GlobalLoggerSettings.start_console_logging()
|
||||
|
||||
staking_provider_uri = os.environ["DEMO_L1_PROVIDER_URI"]
|
||||
network = "lynx"
|
||||
eth_endpoint = os.environ["DEMO_L1_PROVIDER_URI"]
|
||||
domain = TACoDomain.LYNX.name
|
||||
|
||||
coordinator_provider_uri = os.environ["DEMO_L2_PROVIDER_URI"]
|
||||
coordinator_network = "mumbai"
|
||||
polygon_endpoint = os.environ["DEMO_L2_PROVIDER_URI"]
|
||||
|
||||
###############
|
||||
# Enrico
|
||||
|
@ -30,9 +30,13 @@ coordinator_network = "mumbai"
|
|||
|
||||
print("--------- Threshold Encryption ---------")
|
||||
|
||||
registry = ContractRegistry.from_latest_publication(
|
||||
domain=domain,
|
||||
)
|
||||
|
||||
coordinator_agent = CoordinatorAgent(
|
||||
provider_uri=coordinator_provider_uri,
|
||||
registry=ContractRegistry.from_latest_publication(domain=coordinator_network),
|
||||
blockchain_endpoint=polygon_endpoint,
|
||||
registry=registry,
|
||||
)
|
||||
ritual_id = 1 # got this from a side channel
|
||||
ritual = coordinator_agent.get_ritual(ritual_id)
|
||||
|
@ -96,11 +100,10 @@ print(f"\nEncrypted message:\n{bytes(threshold_message_kit).hex()}")
|
|||
print("--------- Threshold Decryption ---------")
|
||||
|
||||
bob = Bob(
|
||||
eth_provider_uri=staking_provider_uri,
|
||||
domain=network,
|
||||
coordinator_provider_uri=coordinator_provider_uri,
|
||||
coordinator_network=coordinator_network,
|
||||
registry=ContractRegistry.from_latest_publication(domain=network),
|
||||
domain=domain,
|
||||
eth_endpoint=eth_endpoint,
|
||||
polygon_endpoint=polygon_endpoint,
|
||||
registry=registry,
|
||||
)
|
||||
|
||||
bob.start_learning_loop(now=True)
|
||||
|
|
|
@ -3,6 +3,7 @@ import os
|
|||
from nucypher_core.ferveo import DkgPublicKey
|
||||
|
||||
from nucypher.blockchain.eth.agents import CoordinatorAgent
|
||||
from nucypher.blockchain.eth.domains import TACoDomain
|
||||
from nucypher.blockchain.eth.registry import ContractRegistry
|
||||
from nucypher.blockchain.eth.signers import InMemorySigner
|
||||
from nucypher.characters.lawful import Bob, Enrico
|
||||
|
@ -18,11 +19,10 @@ LOG_LEVEL = "info"
|
|||
GlobalLoggerSettings.set_log_level(log_level_name=LOG_LEVEL)
|
||||
GlobalLoggerSettings.start_console_logging()
|
||||
|
||||
staking_provider_uri = os.environ["DEMO_L1_PROVIDER_URI"]
|
||||
network = "lynx"
|
||||
eth_endpoint = os.environ["DEMO_L1_PROVIDER_URI"]
|
||||
domain = TACoDomain.LYNX.name
|
||||
|
||||
coordinator_provider_uri = os.environ["DEMO_L2_PROVIDER_URI"]
|
||||
coordinator_network = "mumbai"
|
||||
polygon_endpoint = os.environ["DEMO_L2_PROVIDER_URI"]
|
||||
|
||||
###############
|
||||
# Enrico
|
||||
|
@ -30,9 +30,13 @@ coordinator_network = "mumbai"
|
|||
|
||||
print("--------- Threshold Encryption ---------")
|
||||
|
||||
registry = ContractRegistry.from_latest_publication(
|
||||
domain=domain,
|
||||
)
|
||||
|
||||
coordinator_agent = CoordinatorAgent(
|
||||
provider_uri=coordinator_provider_uri,
|
||||
registry=ContractRegistry.from_latest_publication(domain=coordinator_network),
|
||||
blockchain_endpoint=polygon_endpoint,
|
||||
registry=registry,
|
||||
)
|
||||
ritual_id = 1 # got this from a side channel
|
||||
ritual = coordinator_agent.get_ritual(ritual_id)
|
||||
|
@ -73,11 +77,10 @@ print(f"\nEncrypted message:\n{bytes(threshold_message_kit).hex()}")
|
|||
print("--------- Threshold Decryption ---------")
|
||||
|
||||
bob = Bob(
|
||||
eth_provider_uri=staking_provider_uri,
|
||||
domain=network,
|
||||
coordinator_provider_uri=coordinator_provider_uri,
|
||||
coordinator_network=coordinator_network,
|
||||
registry=ContractRegistry.from_latest_publication(domain=network),
|
||||
domain=domain,
|
||||
eth_endpoint=eth_endpoint,
|
||||
polygon_endpoint=polygon_endpoint,
|
||||
registry=registry,
|
||||
)
|
||||
|
||||
bob.start_learning_loop(now=True)
|
||||
|
|
|
@ -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``.
|
|
@ -0,0 +1 @@
|
|||
Deprecate configuration config/parameters ``pre-payment-network``, ``coordinator_uri`` since the L2 network is implied based on TACo network used.
|
|
@ -14,7 +14,7 @@ __title__ = "nucypher"
|
|||
|
||||
__url__ = "https://github.com/nucypher/nucypher"
|
||||
|
||||
__summary__ = 'A proxy re-encryption network to empower privacy in decentralized systems.'
|
||||
__summary__ = "A threshold access control application to empower privacy in decentralized systems."
|
||||
|
||||
__version__ = "6.2.0"
|
||||
|
||||
|
|
|
@ -30,19 +30,18 @@ from nucypher.acumen.nicknames import Nickname
|
|||
from nucypher.blockchain.eth.agents import (
|
||||
ContractAgency,
|
||||
CoordinatorAgent,
|
||||
NucypherTokenAgent,
|
||||
TACoApplicationAgent,
|
||||
TACoChildApplicationAgent,
|
||||
)
|
||||
from nucypher.blockchain.eth.clients import PUBLIC_CHAINS
|
||||
from nucypher.blockchain.eth.constants import NULL_ADDRESS
|
||||
from nucypher.blockchain.eth.decorators import validate_checksum_address
|
||||
from nucypher.blockchain.eth.domains import TACoDomain
|
||||
from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory
|
||||
from nucypher.blockchain.eth.registry import (
|
||||
ContractRegistry,
|
||||
)
|
||||
from nucypher.blockchain.eth.signers import Signer
|
||||
from nucypher.blockchain.eth.token import NU
|
||||
from nucypher.blockchain.eth.trackers import dkg
|
||||
from nucypher.blockchain.eth.trackers.bonding import OperatorBondedTracker
|
||||
from nucypher.blockchain.eth.utils import truncate_checksum_address
|
||||
|
@ -70,7 +69,7 @@ class BaseActor:
|
|||
@validate_checksum_address
|
||||
def __init__(
|
||||
self,
|
||||
domain: Optional[str],
|
||||
domain: str,
|
||||
registry: ContractRegistry,
|
||||
transacting_power: Optional[TransactingPower] = None,
|
||||
checksum_address: Optional[ChecksumAddress] = None,
|
||||
|
@ -94,6 +93,7 @@ class BaseActor:
|
|||
self.transacting_power = transacting_power
|
||||
self.registry = registry
|
||||
self.network = domain
|
||||
self.taco_domain_info = TACoDomain.get_domain_info(self.network)
|
||||
self._saved_receipts = list() # track receipts of transmitted transactions
|
||||
|
||||
def __repr__(self):
|
||||
|
@ -130,24 +130,6 @@ class NucypherTokenActor(BaseActor):
|
|||
super().__init__(registry=registry, **kwargs)
|
||||
self.__token_agent = None
|
||||
|
||||
@property
|
||||
def token_agent(self):
|
||||
if self.__token_agent:
|
||||
return self.__token_agent
|
||||
self.__token_agent = ContractAgency.get_agent(
|
||||
NucypherTokenAgent,
|
||||
provider_uri=self.eth_provider_uri,
|
||||
registry=self.registry,
|
||||
)
|
||||
return self.__token_agent
|
||||
|
||||
@property
|
||||
def token_balance(self) -> NU:
|
||||
"""Return this actor's current token balance"""
|
||||
balance = int(self.token_agent.get_balance(address=self.checksum_address))
|
||||
nu_balance = NU(balance, 'NuNit')
|
||||
return nu_balance
|
||||
|
||||
|
||||
class Operator(BaseActor):
|
||||
READY_TIMEOUT = None # (None or 0) == indefinite
|
||||
|
@ -158,25 +140,24 @@ class Operator(BaseActor):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
eth_provider_uri: str,
|
||||
coordinator_provider_uri: str,
|
||||
coordinator_network: str,
|
||||
eth_endpoint: str,
|
||||
polygon_endpoint: str,
|
||||
pre_payment_method: ContractPayment,
|
||||
transacting_power: TransactingPower,
|
||||
signer: Signer = None,
|
||||
crypto_power: CryptoPower = None,
|
||||
client_password: str = None,
|
||||
operator_address: Optional[ChecksumAddress] = None,
|
||||
condition_provider_uris: Optional[Dict[int, List[str]]] = None,
|
||||
condition_blockchain_endpoints: Optional[Dict[int, List[str]]] = None,
|
||||
publish_finalization: bool = True, # TODO: Remove this
|
||||
*args,
|
||||
**kwargs,
|
||||
):
|
||||
# Falsy values may be passed down from the superclass
|
||||
if not eth_provider_uri:
|
||||
raise ValueError("Ethereum Provider URI is required to init an operator.")
|
||||
if not coordinator_provider_uri:
|
||||
raise ValueError("Polygon Provider URI is required to init an operator.")
|
||||
if not eth_endpoint:
|
||||
raise ValueError("Ethereum endpoint URI is required to init an operator.")
|
||||
if not polygon_endpoint:
|
||||
raise ValueError("Polygon endpoint URI is required to init an operator.")
|
||||
if not pre_payment_method:
|
||||
raise ValueError("PRE payment method is required to init an operator.")
|
||||
|
||||
|
@ -204,24 +185,21 @@ class Operator(BaseActor):
|
|||
|
||||
self.application_agent = ContractAgency.get_agent(
|
||||
TACoApplicationAgent,
|
||||
provider_uri=eth_provider_uri,
|
||||
blockchain_endpoint=eth_endpoint,
|
||||
registry=self.registry,
|
||||
)
|
||||
|
||||
# TODO: registry usage (and subsequently "network") is inconsistent here
|
||||
coordinator_network_registry = ContractRegistry.from_latest_publication(
|
||||
domain=coordinator_network
|
||||
)
|
||||
registry = ContractRegistry.from_latest_publication(domain=self.network)
|
||||
self.child_application_agent = ContractAgency.get_agent(
|
||||
TACoChildApplicationAgent,
|
||||
registry=coordinator_network_registry,
|
||||
provider_uri=coordinator_provider_uri,
|
||||
registry=registry,
|
||||
blockchain_endpoint=polygon_endpoint,
|
||||
)
|
||||
|
||||
self.coordinator_agent = ContractAgency.get_agent(
|
||||
CoordinatorAgent,
|
||||
registry=coordinator_network_registry,
|
||||
provider_uri=coordinator_provider_uri,
|
||||
registry=registry,
|
||||
blockchain_endpoint=polygon_endpoint,
|
||||
)
|
||||
|
||||
# track active onchain rituals
|
||||
|
@ -242,7 +220,7 @@ class Operator(BaseActor):
|
|||
) # used for secure decryption request channel
|
||||
|
||||
self.condition_providers = self.connect_condition_providers(
|
||||
condition_provider_uris
|
||||
condition_blockchain_endpoints
|
||||
)
|
||||
|
||||
def set_provider_public_key(self) -> Union[TxReceipt, None]:
|
||||
|
@ -266,19 +244,22 @@ class Operator(BaseActor):
|
|||
return provider
|
||||
|
||||
def connect_condition_providers(
|
||||
self, condition_provider_uris: Optional[Dict[int, List[str]]] = None
|
||||
self, condition_blockchain_endpoints: Optional[Dict[int, List[str]]] = None
|
||||
) -> DefaultDict[int, Set[HTTPProvider]]:
|
||||
"""Multi-provider support"""
|
||||
|
||||
# If condition_provider_uris is None the node operator
|
||||
# If condition_blockchain_endpoints is None the node operator
|
||||
# did not configure any additional condition providers.
|
||||
condition_provider_uris = condition_provider_uris or dict()
|
||||
condition_blockchain_endpoints = condition_blockchain_endpoints or dict()
|
||||
|
||||
# These are the chains that the Operator will connect to for conditions evaluation (read-only).
|
||||
condition_providers = defaultdict(set)
|
||||
|
||||
# Now, add any additional providers that were passed in.
|
||||
for chain_id, condition_provider_uris in condition_provider_uris.items():
|
||||
for (
|
||||
chain_id,
|
||||
condition_blockchain_endpoints,
|
||||
) in condition_blockchain_endpoints.items():
|
||||
if not self._is_permitted_condition_chain(chain_id):
|
||||
# this is a safety check to prevent the Operator from connecting to
|
||||
# chains that are not supported by ursulas on the network;
|
||||
|
@ -288,7 +269,7 @@ class Operator(BaseActor):
|
|||
)
|
||||
|
||||
providers = set()
|
||||
for uri in condition_provider_uris:
|
||||
for uri in condition_blockchain_endpoints:
|
||||
provider = self._make_condition_provider(uri)
|
||||
providers.add(provider)
|
||||
|
||||
|
@ -742,10 +723,12 @@ class Operator(BaseActor):
|
|||
class PolicyAuthor(NucypherTokenActor):
|
||||
"""Alice base class for blockchain operations, mocking up new policies!"""
|
||||
|
||||
def __init__(self, eth_provider_uri: str, *args, **kwargs):
|
||||
def __init__(self, eth_endpoint: str, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.application_agent = ContractAgency.get_agent(
|
||||
TACoApplicationAgent, registry=self.registry, provider_uri=eth_provider_uri
|
||||
TACoApplicationAgent,
|
||||
registry=self.registry,
|
||||
blockchain_endpoint=eth_endpoint,
|
||||
)
|
||||
|
||||
def create_policy(self, *args, **kwargs):
|
||||
|
|
|
@ -81,7 +81,7 @@ class EthereumContractAgent:
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
provider_uri: str,
|
||||
blockchain_endpoint: str,
|
||||
registry: ContractRegistry,
|
||||
contract: Optional[Contract] = None,
|
||||
transaction_gas: Optional[Wei] = None,
|
||||
|
@ -91,7 +91,7 @@ class EthereumContractAgent:
|
|||
self.registry = registry
|
||||
|
||||
self.blockchain = BlockchainInterfaceFactory.get_or_create_interface(
|
||||
eth_provider_uri=provider_uri
|
||||
endpoint=blockchain_endpoint
|
||||
)
|
||||
|
||||
if not contract: # Fetch the contract
|
||||
|
@ -106,12 +106,14 @@ class EthereumContractAgent:
|
|||
transaction_gas = EthereumContractAgent.DEFAULT_TRANSACTION_GAS_LIMITS['default']
|
||||
self.transaction_gas = transaction_gas
|
||||
|
||||
self.log.info("Initialized new {} for {} with {} and {}".format(
|
||||
self.__class__.__name__,
|
||||
self.contract.address,
|
||||
self.blockchain.eth_provider_uri,
|
||||
str(self.registry)
|
||||
))
|
||||
self.log.info(
|
||||
"Initialized new {} for {} with {} and {}".format(
|
||||
self.__class__.__name__,
|
||||
self.contract.address,
|
||||
self.blockchain.endpoint,
|
||||
str(self.registry),
|
||||
)
|
||||
)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
class_name = self.__class__.__name__
|
||||
|
@ -845,15 +847,15 @@ class ContractAgency:
|
|||
cls,
|
||||
agent_class: Type[types.Agent],
|
||||
registry: Optional[ContractRegistry],
|
||||
provider_uri: Optional[str],
|
||||
blockchain_endpoint: Optional[str],
|
||||
contract_version: Optional[str] = None,
|
||||
) -> types.Agent:
|
||||
if not issubclass(agent_class, EthereumContractAgent):
|
||||
raise TypeError("Only agent subclasses can be used from the agency.")
|
||||
|
||||
if not provider_uri:
|
||||
if not blockchain_endpoint:
|
||||
raise ValueError(
|
||||
"Need to specify an Ethereum provider URI in order to get an agent from the ContractAgency"
|
||||
"Need to specify a blockchain provider URI in order to get an agent from the ContractAgency"
|
||||
)
|
||||
|
||||
if not registry:
|
||||
|
@ -869,7 +871,7 @@ class ContractAgency:
|
|||
types.Agent,
|
||||
agent_class(
|
||||
registry=registry,
|
||||
provider_uri=provider_uri,
|
||||
blockchain_endpoint=blockchain_endpoint,
|
||||
),
|
||||
)
|
||||
cls.__agents[registry_id] = cls.__agents.get(registry_id, dict())
|
||||
|
@ -889,7 +891,7 @@ class ContractAgency:
|
|||
cls,
|
||||
contract_name: str,
|
||||
registry: ContractRegistry,
|
||||
provider_uri: str,
|
||||
blockchain_endpoint: str,
|
||||
contract_version: Optional[str] = None,
|
||||
) -> EthereumContractAgent:
|
||||
agent_name: str = cls._contract_name_to_agent_name(name=contract_name)
|
||||
|
@ -898,7 +900,7 @@ class ContractAgency:
|
|||
agent: EthereumContractAgent = cls.get_agent(
|
||||
agent_class=agent_class,
|
||||
registry=registry,
|
||||
provider_uri=provider_uri,
|
||||
blockchain_endpoint=blockchain_endpoint,
|
||||
contract_version=contract_version
|
||||
)
|
||||
return agent
|
||||
|
|
|
@ -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.")
|
|
@ -6,7 +6,7 @@ from urllib.parse import urlparse
|
|||
|
||||
import requests
|
||||
from constant_sorrow.constants import (
|
||||
INSUFFICIENT_ETH,
|
||||
INSUFFICIENT_FUNDS,
|
||||
NO_BLOCKCHAIN_CONNECTION,
|
||||
UNKNOWN_TX_STATUS,
|
||||
)
|
||||
|
@ -82,7 +82,7 @@ class BlockchainInterface:
|
|||
pass
|
||||
|
||||
REASONS = {
|
||||
INSUFFICIENT_ETH: 'insufficient funds for gas * price + value',
|
||||
INSUFFICIENT_FUNDS: "insufficient funds for gas * price + value",
|
||||
}
|
||||
|
||||
class TransactionFailed(InterfaceError):
|
||||
|
@ -100,7 +100,7 @@ class BlockchainInterface:
|
|||
self.payload = transaction_dict
|
||||
self.contract_function = contract_function
|
||||
self.failures = {
|
||||
BlockchainInterface.REASONS[INSUFFICIENT_ETH]: self.insufficient_eth
|
||||
BlockchainInterface.REASONS[INSUFFICIENT_FUNDS]: self.insufficient_funds
|
||||
}
|
||||
self.message = self.failures.get(self.base_message, self.default)
|
||||
super().__init__(self.message, *args)
|
||||
|
@ -120,7 +120,7 @@ class BlockchainInterface:
|
|||
return balance
|
||||
|
||||
@property
|
||||
def insufficient_eth(self) -> str:
|
||||
def insufficient_funds(self) -> str:
|
||||
try:
|
||||
transaction_fee = self.payload['gas'] * self.payload['gasPrice']
|
||||
except KeyError:
|
||||
|
@ -132,15 +132,16 @@ class BlockchainInterface:
|
|||
f'but sender only has {prettify_eth_amount(self.get_balance())}.'
|
||||
return message
|
||||
|
||||
def __init__(self,
|
||||
emitter=None, # TODO # 1754
|
||||
poa: bool = None,
|
||||
light: bool = False,
|
||||
eth_provider_uri: str = NO_BLOCKCHAIN_CONNECTION,
|
||||
eth_provider: BaseProvider = NO_BLOCKCHAIN_CONNECTION,
|
||||
gas_strategy: Optional[Union[str, Callable]] = None,
|
||||
max_gas_price: Optional[int] = None):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
emitter=None, # TODO # 1754
|
||||
poa: bool = None,
|
||||
light: bool = False,
|
||||
endpoint: str = NO_BLOCKCHAIN_CONNECTION,
|
||||
provider: BaseProvider = NO_BLOCKCHAIN_CONNECTION,
|
||||
gas_strategy: Optional[Union[str, Callable]] = None,
|
||||
max_gas_price: Optional[int] = None,
|
||||
):
|
||||
"""
|
||||
TODO: #1502 - Move to API docs.
|
||||
|
||||
|
@ -206,8 +207,8 @@ class BlockchainInterface:
|
|||
|
||||
self.log = Logger('Blockchain')
|
||||
self.poa = poa
|
||||
self.eth_provider_uri = eth_provider_uri
|
||||
self._eth_provider = eth_provider
|
||||
self.endpoint = endpoint
|
||||
self._provider = provider
|
||||
self.w3 = NO_BLOCKCHAIN_CONNECTION
|
||||
self.client = NO_BLOCKCHAIN_CONNECTION
|
||||
self.is_light = light
|
||||
|
@ -219,7 +220,7 @@ class BlockchainInterface:
|
|||
self.max_gas_price = max_gas_price
|
||||
|
||||
def __repr__(self):
|
||||
r = '{name}({uri})'.format(name=self.__class__.__name__, uri=self.eth_provider_uri)
|
||||
r = "{name}({uri})".format(name=self.__class__.__name__, uri=self.endpoint)
|
||||
return r
|
||||
|
||||
def get_blocktime(self):
|
||||
|
@ -292,23 +293,30 @@ class BlockchainInterface:
|
|||
|
||||
def connect(self):
|
||||
|
||||
eth_provider_uri = self.eth_provider_uri
|
||||
self.log.info(f"Using external Web3 Provider '{self.eth_provider_uri}'")
|
||||
endpoint = self.endpoint
|
||||
self.log.info(f"Using external Web3 Provider '{self.endpoint}'")
|
||||
|
||||
# Attach Provider
|
||||
self._attach_eth_provider(eth_provider=self._eth_provider, eth_provider_uri=eth_provider_uri)
|
||||
self.log.info("Connecting to {}".format(self.eth_provider_uri))
|
||||
if self._eth_provider is NO_BLOCKCHAIN_CONNECTION:
|
||||
self._attach_blockchain_provider(
|
||||
provider=self._provider,
|
||||
endpoint=endpoint,
|
||||
)
|
||||
self.log.info("Connecting to {}".format(self.endpoint))
|
||||
if self._provider is NO_BLOCKCHAIN_CONNECTION:
|
||||
raise self.NoProvider("There are no configured blockchain providers")
|
||||
|
||||
# Connect if not connected
|
||||
try:
|
||||
self.w3 = self.Web3(provider=self._eth_provider)
|
||||
self.w3 = self.Web3(provider=self._provider)
|
||||
self.client = EthereumClient.from_w3(w3=self.w3)
|
||||
except requests.ConnectionError: # RPC
|
||||
raise self.ConnectionFailed(f'Connection Failed - {str(self.eth_provider_uri)} - is RPC enabled?')
|
||||
except FileNotFoundError: # IPC File Protocol
|
||||
raise self.ConnectionFailed(f'Connection Failed - {str(self.eth_provider_uri)} - is IPC enabled?')
|
||||
raise self.ConnectionFailed(
|
||||
f"Connection Failed - {str(self.endpoint)} - is RPC enabled?"
|
||||
)
|
||||
except FileNotFoundError: # IPC File Protocol
|
||||
raise self.ConnectionFailed(
|
||||
f"Connection Failed - {str(self.endpoint)} - is IPC enabled?"
|
||||
)
|
||||
else:
|
||||
self.attach_middleware()
|
||||
|
||||
|
@ -316,20 +324,22 @@ class BlockchainInterface:
|
|||
|
||||
@property
|
||||
def provider(self) -> BaseProvider:
|
||||
return self._eth_provider
|
||||
return self._provider
|
||||
|
||||
def _attach_eth_provider(self,
|
||||
eth_provider: Optional[BaseProvider] = None,
|
||||
eth_provider_uri: str = None) -> None:
|
||||
def _attach_blockchain_provider(
|
||||
self,
|
||||
provider: Optional[BaseProvider] = None,
|
||||
endpoint: str = None,
|
||||
) -> None:
|
||||
"""
|
||||
https://web3py.readthedocs.io/en/latest/providers.html#providers
|
||||
"""
|
||||
|
||||
if not eth_provider_uri and not eth_provider:
|
||||
if not endpoint and not provider:
|
||||
raise self.NoProvider("No URI or provider instances supplied.")
|
||||
|
||||
if eth_provider_uri and not eth_provider:
|
||||
uri_breakdown = urlparse(eth_provider_uri)
|
||||
if endpoint and not provider:
|
||||
uri_breakdown = urlparse(endpoint)
|
||||
|
||||
if uri_breakdown.scheme == 'tester':
|
||||
providers = {
|
||||
|
@ -352,19 +362,23 @@ class BlockchainInterface:
|
|||
|
||||
# auto-detect for file based ipc
|
||||
if not provider_scheme:
|
||||
if Path(eth_provider_uri).is_file():
|
||||
if Path(endpoint).is_file():
|
||||
# file is available - assume ipc/file scheme
|
||||
provider_scheme = 'file'
|
||||
self.log.info(f"Auto-detected provider scheme as 'file://' for provider {eth_provider_uri}")
|
||||
provider_scheme = "file"
|
||||
self.log.info(
|
||||
f"Auto-detected provider scheme as 'file://' for provider {endpoint}"
|
||||
)
|
||||
|
||||
try:
|
||||
self._eth_provider = providers[provider_scheme](eth_provider_uri)
|
||||
self._provider = providers[provider_scheme](endpoint)
|
||||
except KeyError:
|
||||
raise self.UnsupportedProvider(f"{eth_provider_uri} is an invalid or unsupported blockchain provider URI")
|
||||
raise self.UnsupportedProvider(
|
||||
f"{endpoint} is an invalid or unsupported blockchain provider URI"
|
||||
)
|
||||
else:
|
||||
self.eth_provider_uri = eth_provider_uri or NO_BLOCKCHAIN_CONNECTION
|
||||
self.endpoint = endpoint or NO_BLOCKCHAIN_CONNECTION
|
||||
else:
|
||||
self._eth_provider = eth_provider
|
||||
self._provider = provider
|
||||
|
||||
@classmethod
|
||||
def _handle_failed_transaction(cls,
|
||||
|
@ -689,11 +703,11 @@ class BlockchainInterfaceFactory:
|
|||
return cls._instance
|
||||
|
||||
@classmethod
|
||||
def is_interface_initialized(cls, eth_provider_uri: str) -> bool:
|
||||
def is_interface_initialized(cls, endpoint: str) -> bool:
|
||||
"""
|
||||
Returns True if there is an existing connection with an equal eth_provider_uri.
|
||||
Returns True if there is an existing connection with an equal endpoint.
|
||||
"""
|
||||
return bool(cls._interfaces.get(eth_provider_uri, False))
|
||||
return bool(cls._interfaces.get(endpoint, False))
|
||||
|
||||
@classmethod
|
||||
def register_interface(cls,
|
||||
|
@ -702,48 +716,59 @@ class BlockchainInterfaceFactory:
|
|||
force: bool = False
|
||||
) -> None:
|
||||
|
||||
eth_provider_uri = interface.eth_provider_uri
|
||||
if (eth_provider_uri in cls._interfaces) and not force:
|
||||
raise cls.InterfaceAlreadyInitialized(f"A connection already exists for {eth_provider_uri}. "
|
||||
"Use .get_interface instead.")
|
||||
endpoint = interface.endpoint
|
||||
if (endpoint in cls._interfaces) and not force:
|
||||
raise cls.InterfaceAlreadyInitialized(
|
||||
f"A connection already exists for {endpoint}. "
|
||||
"Use .get_interface instead."
|
||||
)
|
||||
cached = cls.CachedInterface(interface=interface, emitter=emitter)
|
||||
cls._interfaces[eth_provider_uri] = cached
|
||||
cls._interfaces[endpoint] = cached
|
||||
|
||||
@classmethod
|
||||
def initialize_interface(cls,
|
||||
eth_provider_uri: str,
|
||||
emitter=None,
|
||||
interface_class: Interfaces = None,
|
||||
*interface_args,
|
||||
**interface_kwargs
|
||||
) -> None:
|
||||
if not eth_provider_uri:
|
||||
def initialize_interface(
|
||||
cls,
|
||||
endpoint: str,
|
||||
emitter=None,
|
||||
interface_class: Interfaces = None,
|
||||
*interface_args,
|
||||
**interface_kwargs,
|
||||
) -> None:
|
||||
if not endpoint:
|
||||
# Prevent empty strings and Falsy
|
||||
raise BlockchainInterface.UnsupportedProvider(f"'{eth_provider_uri}' is not a valid provider URI")
|
||||
raise BlockchainInterface.UnsupportedProvider(
|
||||
f"'{endpoint}' is not a valid provider URI"
|
||||
)
|
||||
|
||||
if eth_provider_uri in cls._interfaces:
|
||||
raise cls.InterfaceAlreadyInitialized(f"A connection already exists for {eth_provider_uri}. "
|
||||
f"Use .get_interface instead.")
|
||||
if endpoint in cls._interfaces:
|
||||
raise cls.InterfaceAlreadyInitialized(
|
||||
f"A connection already exists for {endpoint}. "
|
||||
f"Use .get_interface instead."
|
||||
)
|
||||
|
||||
# Interface does not exist, initialize a new one.
|
||||
if not interface_class:
|
||||
interface_class = cls._default_interface_class
|
||||
interface = interface_class(eth_provider_uri=eth_provider_uri,
|
||||
*interface_args,
|
||||
**interface_kwargs)
|
||||
interface = interface_class(
|
||||
endpoint=endpoint, *interface_args, **interface_kwargs
|
||||
)
|
||||
interface.connect()
|
||||
cls._interfaces[eth_provider_uri] = cls.CachedInterface(interface=interface, emitter=emitter)
|
||||
cls._interfaces[endpoint] = cls.CachedInterface(
|
||||
interface=interface, emitter=emitter
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_interface(cls, eth_provider_uri: str = None) -> Interfaces:
|
||||
def get_interface(cls, endpoint: str = None) -> Interfaces:
|
||||
|
||||
# Try to get an existing cached interface.
|
||||
if eth_provider_uri:
|
||||
if endpoint:
|
||||
try:
|
||||
cached_interface = cls._interfaces[eth_provider_uri]
|
||||
cached_interface = cls._interfaces[endpoint]
|
||||
except KeyError:
|
||||
raise cls.InterfaceNotInitialized(f"There is no connection for {eth_provider_uri}. "
|
||||
f"Call .initialize_connection, then try again.")
|
||||
raise cls.InterfaceNotInitialized(
|
||||
f"There is no connection for {endpoint}. "
|
||||
f"Call .initialize_connection, then try again."
|
||||
)
|
||||
|
||||
# Try to use the most recently created interface by default.
|
||||
else:
|
||||
|
@ -761,14 +786,16 @@ class BlockchainInterfaceFactory:
|
|||
return interface
|
||||
|
||||
@classmethod
|
||||
def get_or_create_interface(cls,
|
||||
eth_provider_uri: str,
|
||||
*interface_args,
|
||||
**interface_kwargs
|
||||
) -> BlockchainInterface:
|
||||
def get_or_create_interface(
|
||||
cls, endpoint: str, *interface_args, **interface_kwargs
|
||||
) -> BlockchainInterface:
|
||||
try:
|
||||
interface = cls.get_interface(eth_provider_uri=eth_provider_uri)
|
||||
interface = cls.get_interface(endpoint=endpoint)
|
||||
except (cls.InterfaceNotInitialized, cls.NoRegisteredInterfaces):
|
||||
cls.initialize_interface(eth_provider_uri=eth_provider_uri, *interface_args, **interface_kwargs)
|
||||
interface = cls.get_interface(eth_provider_uri=eth_provider_uri)
|
||||
cls.initialize_interface(
|
||||
endpoint=endpoint,
|
||||
*interface_args,
|
||||
**interface_kwargs,
|
||||
)
|
||||
interface = cls.get_interface(endpoint=endpoint)
|
||||
return interface
|
||||
|
|
|
@ -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."
|
||||
)
|
|
@ -14,25 +14,33 @@ class ProviderError(Exception):
|
|||
pass
|
||||
|
||||
|
||||
def _get_IPC_provider(eth_provider_uri) -> BaseProvider:
|
||||
uri_breakdown = urlparse(eth_provider_uri)
|
||||
def _get_IPC_provider(endpoint) -> BaseProvider:
|
||||
uri_breakdown = urlparse(endpoint)
|
||||
from nucypher.blockchain.eth.interfaces import BlockchainInterface
|
||||
return IPCProvider(ipc_path=uri_breakdown.path,
|
||||
timeout=BlockchainInterface.TIMEOUT,
|
||||
request_kwargs={'timeout': BlockchainInterface.TIMEOUT})
|
||||
|
||||
|
||||
def _get_HTTP_provider(eth_provider_uri) -> BaseProvider:
|
||||
def _get_HTTP_provider(endpoint) -> BaseProvider:
|
||||
from nucypher.blockchain.eth.interfaces import BlockchainInterface
|
||||
return HTTPProvider(endpoint_uri=eth_provider_uri, request_kwargs={'timeout': BlockchainInterface.TIMEOUT})
|
||||
|
||||
return HTTPProvider(
|
||||
endpoint_uri=endpoint,
|
||||
request_kwargs={"timeout": BlockchainInterface.TIMEOUT},
|
||||
)
|
||||
|
||||
|
||||
def _get_websocket_provider(eth_provider_uri) -> BaseProvider:
|
||||
def _get_websocket_provider(endpoint) -> BaseProvider:
|
||||
from nucypher.blockchain.eth.interfaces import BlockchainInterface
|
||||
return WebsocketProvider(endpoint_uri=eth_provider_uri, websocket_kwargs={'timeout': BlockchainInterface.TIMEOUT})
|
||||
|
||||
return WebsocketProvider(
|
||||
endpoint_uri=endpoint,
|
||||
websocket_kwargs={"timeout": BlockchainInterface.TIMEOUT},
|
||||
)
|
||||
|
||||
|
||||
def _get_auto_provider(eth_provider_uri) -> BaseProvider:
|
||||
def _get_auto_provider(endpoint) -> BaseProvider:
|
||||
from web3.auto import w3
|
||||
# how-automated-detection-works: https://web3py.readthedocs.io/en/latest/providers.html
|
||||
connected = w3.isConnected()
|
||||
|
@ -61,7 +69,7 @@ def _get_ethereum_tester(test_backend: Union[PyEVMBackend, MockBackend]) -> Ethe
|
|||
return provider
|
||||
|
||||
|
||||
def _get_pyevm_test_provider(eth_provider_uri) -> BaseProvider:
|
||||
def _get_pyevm_test_provider(endpoint) -> BaseProvider:
|
||||
""" Test provider entry-point"""
|
||||
# https://github.com/ethereum/eth-tester#pyevm-experimental
|
||||
pyevm_eth_tester = _get_pyevm_test_backend()
|
||||
|
@ -69,13 +77,13 @@ def _get_pyevm_test_provider(eth_provider_uri) -> BaseProvider:
|
|||
return provider
|
||||
|
||||
|
||||
def _get_mock_test_provider(eth_provider_uri) -> BaseProvider:
|
||||
def _get_mock_test_provider(endpoint) -> BaseProvider:
|
||||
# https://github.com/ethereum/eth-tester#mockbackend
|
||||
mock_backend = MockBackend()
|
||||
provider = _get_ethereum_tester(test_backend=mock_backend)
|
||||
return provider
|
||||
|
||||
|
||||
def _get_tester_ganache(eth_provider_uri=None) -> BaseProvider:
|
||||
endpoint_uri = eth_provider_uri or 'http://localhost:7545'
|
||||
def _get_tester_ganache(endpoint=None) -> BaseProvider:
|
||||
endpoint_uri = endpoint or "http://localhost:7545"
|
||||
return HTTPProvider(endpoint_uri=endpoint_uri)
|
||||
|
|
|
@ -9,7 +9,7 @@ import requests
|
|||
from requests import Response
|
||||
from web3.types import ABI
|
||||
|
||||
from nucypher.blockchain.eth.networks import NetworksInventory
|
||||
from nucypher.blockchain.eth.domains import TACoDomain
|
||||
from nucypher.utilities.logging import Logger
|
||||
|
||||
RegistryArtifact = Dict[str, Union[str, ABI]]
|
||||
|
@ -34,10 +34,10 @@ class RegistrySource(ABC):
|
|||
"""Raised when there are no available registry sources"""
|
||||
|
||||
def __init__(self, domain: str, *args, **kwargs):
|
||||
if domain not in NetworksInventory.NETWORKS:
|
||||
if domain not in TACoDomain.SUPPORTED_DOMAIN_NAMES:
|
||||
raise ValueError(
|
||||
f"{self.__class__.__name__} not available for domain '{domain}'. "
|
||||
f"Valid options are: {', '.join(list(NetworksInventory.NETWORKS))}"
|
||||
f"Valid options are: {', '.join(list(TACoDomain.SUPPORTED_DOMAIN_NAMES))}"
|
||||
)
|
||||
self.domain = domain
|
||||
self.data = self.get()
|
||||
|
|
|
@ -34,7 +34,9 @@ class Web3Signer(Signer):
|
|||
BlockchainInterfaceFactory,
|
||||
)
|
||||
try:
|
||||
blockchain = BlockchainInterfaceFactory.get_or_create_interface(eth_provider_uri=uri)
|
||||
blockchain = BlockchainInterfaceFactory.get_or_create_interface(
|
||||
endpoint=uri
|
||||
)
|
||||
except BlockchainInterface.UnsupportedProvider:
|
||||
raise cls.InvalidSignerURI(uri)
|
||||
signer = cls(client=blockchain.client)
|
||||
|
|
|
@ -20,7 +20,7 @@ class OperatorBondedTracker(SimpleTask):
|
|||
application_agent = ContractAgency.get_agent(
|
||||
TACoApplicationAgent,
|
||||
registry=self._ursula.registry,
|
||||
provider_uri=self._ursula.eth_provider_uri,
|
||||
blockchain_endpoint=self._ursula.eth_endpoint,
|
||||
)
|
||||
# use TACo root since unbonding happens at root and not child (more immediate this way)
|
||||
staking_provider_address = application_agent.get_staking_provider_from_operator(
|
||||
|
|
|
@ -34,7 +34,8 @@ class Character(Learner):
|
|||
def __init__(
|
||||
self,
|
||||
domain: str,
|
||||
eth_provider_uri: str = None,
|
||||
eth_endpoint: str = None,
|
||||
polygon_endpoint: str = None,
|
||||
known_node_class: object = None,
|
||||
is_me: bool = True,
|
||||
checksum_address: str = None,
|
||||
|
@ -113,14 +114,17 @@ class Character(Learner):
|
|||
except NoSigningPower:
|
||||
self._stamp = NO_SIGNING_POWER
|
||||
|
||||
self.eth_provider_uri = eth_provider_uri
|
||||
self.eth_endpoint = eth_endpoint
|
||||
self.polygon_endpoint = polygon_endpoint
|
||||
|
||||
self.registry = registry or ContractRegistry.from_latest_publication(
|
||||
domain=domain
|
||||
) # See #1580
|
||||
)
|
||||
|
||||
# REST
|
||||
self.network_middleware = network_middleware or RestMiddleware(registry=self.registry,
|
||||
eth_provider_uri=eth_provider_uri)
|
||||
self.network_middleware = network_middleware or RestMiddleware(
|
||||
registry=self.registry, eth_endpoint=eth_endpoint
|
||||
)
|
||||
|
||||
# Learner
|
||||
Learner.__init__(self,
|
||||
|
|
|
@ -131,7 +131,7 @@ class Alice(Character, actors.PolicyAuthor):
|
|||
self,
|
||||
# Mode
|
||||
is_me: bool = True,
|
||||
eth_provider_uri: str = None,
|
||||
eth_endpoint: str = None,
|
||||
signer=None,
|
||||
# Ownership
|
||||
checksum_address: Optional[ChecksumAddress] = None,
|
||||
|
@ -170,7 +170,7 @@ class Alice(Character, actors.PolicyAuthor):
|
|||
self,
|
||||
known_node_class=Ursula,
|
||||
is_me=is_me,
|
||||
eth_provider_uri=eth_provider_uri,
|
||||
eth_endpoint=eth_endpoint,
|
||||
checksum_address=checksum_address,
|
||||
network_middleware=network_middleware,
|
||||
*args,
|
||||
|
@ -179,7 +179,7 @@ class Alice(Character, actors.PolicyAuthor):
|
|||
|
||||
if is_me: # TODO: #289
|
||||
blockchain = BlockchainInterfaceFactory.get_interface(
|
||||
eth_provider_uri=self.eth_provider_uri
|
||||
endpoint=self.eth_endpoint
|
||||
)
|
||||
signer = signer or Web3Signer(
|
||||
blockchain.client
|
||||
|
@ -193,7 +193,7 @@ class Alice(Character, actors.PolicyAuthor):
|
|||
domain=self.domain,
|
||||
transacting_power=self.transacting_power,
|
||||
registry=self.registry,
|
||||
eth_provider_uri=eth_provider_uri,
|
||||
eth_endpoint=eth_endpoint,
|
||||
)
|
||||
|
||||
self.log = Logger(self.__class__.__name__)
|
||||
|
@ -216,7 +216,7 @@ class Alice(Character, actors.PolicyAuthor):
|
|||
|
||||
def add_active_policy(self, active_policy):
|
||||
"""
|
||||
Adds a Policy object that is active on the NuCypher network to Alice's
|
||||
Adds a Policy object that is active on the TACo network to Alice's
|
||||
`active_policies` dictionary by the policy ID.
|
||||
"""
|
||||
if active_policy.hrac in self.active_policies:
|
||||
|
@ -458,9 +458,8 @@ class Bob(Character):
|
|||
self,
|
||||
is_me: bool = True,
|
||||
verify_node_bonding: bool = False,
|
||||
eth_provider_uri: str = None,
|
||||
coordinator_provider_uri: str = None, # TODO: Move to a higher level and formalize
|
||||
coordinator_network: str = None, # TODO: Move to a higher level and formalize
|
||||
eth_endpoint: str = None,
|
||||
polygon_endpoint: str = None,
|
||||
*args,
|
||||
**kwargs,
|
||||
) -> None:
|
||||
|
@ -469,26 +468,22 @@ class Bob(Character):
|
|||
is_me=is_me,
|
||||
known_node_class=Ursula,
|
||||
verify_node_bonding=verify_node_bonding,
|
||||
eth_provider_uri=eth_provider_uri,
|
||||
eth_endpoint=eth_endpoint,
|
||||
polygon_endpoint=polygon_endpoint,
|
||||
*args,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
coordinator_agent = None
|
||||
if coordinator_provider_uri:
|
||||
if not coordinator_network:
|
||||
raise ValueError(
|
||||
"If coordinator_provider_uri is set, coordinator_network must also be set"
|
||||
)
|
||||
if polygon_endpoint:
|
||||
coordinator_agent = ContractAgency.get_agent(
|
||||
CoordinatorAgent,
|
||||
provider_uri=coordinator_provider_uri,
|
||||
blockchain_endpoint=polygon_endpoint,
|
||||
registry=ContractRegistry.from_latest_publication(
|
||||
domain=coordinator_network
|
||||
domain=self.domain,
|
||||
),
|
||||
)
|
||||
self.coordinator_agent = coordinator_agent
|
||||
self.coordinator_network = coordinator_network
|
||||
|
||||
# Cache of decrypted treasure maps
|
||||
self._treasure_maps: Dict[int, TreasureMap] = {}
|
||||
|
@ -705,9 +700,7 @@ class Bob(Character):
|
|||
|
||||
def _get_coordinator_agent(self) -> CoordinatorAgent:
|
||||
if not self.coordinator_agent:
|
||||
raise ValueError(
|
||||
"No coordinator provider URI provided in Bob's constructor."
|
||||
)
|
||||
raise ValueError("No polygon endpoint URI provided in Bob's constructor.")
|
||||
|
||||
return self.coordinator_agent
|
||||
|
||||
|
@ -825,8 +818,9 @@ class Ursula(Teacher, Character, Operator):
|
|||
client_password: Optional[str] = None,
|
||||
transacting_power: Optional[TransactingPower] = None,
|
||||
operator_signature_from_metadata=NOT_SIGNED,
|
||||
eth_provider_uri: Optional[str] = None,
|
||||
condition_provider_uris: Optional[Dict[int, List[str]]] = None,
|
||||
eth_endpoint: Optional[str] = None,
|
||||
polygon_endpoint: Optional[str] = None,
|
||||
condition_blockchain_endpoints: Optional[Dict[int, List[str]]] = None,
|
||||
pre_payment_method: Optional[Union[PaymentMethod, ContractPayment]] = None,
|
||||
# Character
|
||||
abort_on_learning_error: bool = False,
|
||||
|
@ -844,7 +838,8 @@ class Ursula(Teacher, Character, Operator):
|
|||
domain=domain,
|
||||
known_node_class=Ursula,
|
||||
include_self_in_the_state=True,
|
||||
eth_provider_uri=eth_provider_uri,
|
||||
eth_endpoint=eth_endpoint,
|
||||
polygon_endpoint=polygon_endpoint,
|
||||
**character_kwargs,
|
||||
)
|
||||
|
||||
|
@ -863,13 +858,12 @@ class Ursula(Teacher, Character, Operator):
|
|||
signer=self.signer,
|
||||
crypto_power=self._crypto_power,
|
||||
operator_address=operator_address,
|
||||
eth_provider_uri=eth_provider_uri,
|
||||
eth_endpoint=eth_endpoint,
|
||||
polygon_endpoint=polygon_endpoint,
|
||||
pre_payment_method=pre_payment_method,
|
||||
client_password=client_password,
|
||||
condition_provider_uris=condition_provider_uris,
|
||||
coordinator_provider_uri=pre_payment_method.provider,
|
||||
condition_blockchain_endpoints=condition_blockchain_endpoints,
|
||||
transacting_power=transacting_power,
|
||||
coordinator_network=pre_payment_method.network,
|
||||
)
|
||||
|
||||
except Exception:
|
||||
|
@ -997,11 +991,9 @@ class Ursula(Teacher, Character, Operator):
|
|||
|
||||
# Connect to Provider
|
||||
if not BlockchainInterfaceFactory.is_interface_initialized(
|
||||
eth_provider_uri=self.eth_provider_uri
|
||||
endpoint=self.eth_endpoint
|
||||
):
|
||||
BlockchainInterfaceFactory.initialize_interface(
|
||||
eth_provider_uri=self.eth_provider_uri
|
||||
)
|
||||
BlockchainInterfaceFactory.initialize_interface(endpoint=self.eth_endpoint)
|
||||
|
||||
if preflight:
|
||||
self.__preflight()
|
||||
|
@ -1189,15 +1181,15 @@ class Ursula(Teacher, Character, Operator):
|
|||
return cls.from_seed_and_stake_info(seed_uri=seed_uri, *args, **kwargs)
|
||||
|
||||
@classmethod
|
||||
def seednode_for_network(cls, network: str, provider_uri: str) -> "Ursula":
|
||||
def seednode_for_domain(cls, domain: str, eth_endpoint: str) -> "Ursula":
|
||||
"""Returns a default seednode ursula for a given network."""
|
||||
try:
|
||||
url = TEACHER_NODES[network][0]
|
||||
url = TEACHER_NODES[domain][0]
|
||||
except KeyError:
|
||||
raise ValueError(f'"{network}" is not a known network.')
|
||||
raise ValueError(f'"{domain}" is not a known domain.')
|
||||
except IndexError:
|
||||
raise ValueError(f'No default seednodes available for "{network}".')
|
||||
ursula = cls.from_seed_and_stake_info(seed_uri=url, provider_uri=provider_uri)
|
||||
raise ValueError(f'No default seednodes available for "{domain}".')
|
||||
ursula = cls.from_seed_and_stake_info(seed_uri=url, eth_endpoint=eth_endpoint)
|
||||
return ursula
|
||||
|
||||
@classmethod
|
||||
|
@ -1205,7 +1197,7 @@ class Ursula(Teacher, Character, Operator):
|
|||
cls,
|
||||
teacher_uri: str,
|
||||
min_stake: int,
|
||||
provider_uri: str,
|
||||
eth_endpoint: str,
|
||||
registry: ContractRegistry = None,
|
||||
network_middleware: RestMiddleware = None,
|
||||
retry_attempts: int = 2,
|
||||
|
@ -1220,7 +1212,7 @@ class Ursula(Teacher, Character, Operator):
|
|||
try:
|
||||
teacher = cls.from_seed_and_stake_info(
|
||||
seed_uri=teacher_uri,
|
||||
provider_uri=provider_uri,
|
||||
eth_endpoint=eth_endpoint,
|
||||
minimum_stake=min_stake,
|
||||
network_middleware=network_middleware,
|
||||
registry=registry,
|
||||
|
@ -1244,14 +1236,14 @@ class Ursula(Teacher, Character, Operator):
|
|||
def from_seed_and_stake_info(
|
||||
cls,
|
||||
seed_uri: str,
|
||||
provider_uri: str,
|
||||
eth_endpoint: str,
|
||||
registry: ContractRegistry = None,
|
||||
minimum_stake: int = 0,
|
||||
network_middleware: RestMiddleware = None,
|
||||
) -> Union["Ursula", "NodeSprout"]:
|
||||
if network_middleware is None:
|
||||
network_middleware = RestMiddleware(
|
||||
registry=registry, eth_provider_uri=provider_uri
|
||||
registry=registry, eth_endpoint=eth_endpoint
|
||||
)
|
||||
|
||||
# Parse node URI
|
||||
|
@ -1280,7 +1272,9 @@ class Ursula(Teacher, Character, Operator):
|
|||
# Check the node's stake (optional)
|
||||
if minimum_stake > 0 and staking_provider_address:
|
||||
application_agent = ContractAgency.get_agent(
|
||||
TACoApplicationAgent, provider_uri=provider_uri, registry=registry
|
||||
TACoApplicationAgent,
|
||||
blockchain_endpoint=eth_endpoint,
|
||||
registry=registry,
|
||||
)
|
||||
seednode_stake = application_agent.get_authorized_stake(
|
||||
staking_provider=staking_provider_address
|
||||
|
|
|
@ -42,26 +42,25 @@ class Vladimir(Ursula):
|
|||
raise DevelopmentInstallationRequired(
|
||||
importable_name="tests.utils.middleware.EvilMiddleWare"
|
||||
)
|
||||
blockchain = target_ursula.application_agent.blockchain
|
||||
cls.network_middleware = EvilMiddleWare(
|
||||
eth_provider_uri=blockchain.eth_provider_uri
|
||||
)
|
||||
eth_blockchain = target_ursula.application_agent.blockchain
|
||||
cls.network_middleware = EvilMiddleWare(eth_endpoint=eth_blockchain.endpoint)
|
||||
|
||||
polygon_blockchain = target_ursula.child_application_agent.blockchain
|
||||
|
||||
crypto_power = CryptoPower(power_ups=target_ursula._default_crypto_powerups)
|
||||
|
||||
cls.attach_transacting_key(blockchain=blockchain)
|
||||
cls.attach_transacting_key(blockchain=eth_blockchain)
|
||||
|
||||
# Vladimir does not care about payment.
|
||||
bogus_pre_payment_method = FreeReencryptions()
|
||||
bogus_pre_payment_method.provider = Mock()
|
||||
bogus_pre_payment_method.agent = Mock()
|
||||
bogus_pre_payment_method.network = TEMPORARY_DOMAIN
|
||||
bogus_pre_payment_method.agent.blockchain.client.chain_id = (
|
||||
blockchain.client.chain_id
|
||||
polygon_blockchain.client.chain_id
|
||||
)
|
||||
mock.patch(
|
||||
"mock.interfaces.MockBlockchain.client.chain_id",
|
||||
new_callable=mock.PropertyMock(return_value=blockchain.client.chain_id),
|
||||
new_callable=mock.PropertyMock(return_value=eth_blockchain.client.chain_id),
|
||||
)
|
||||
|
||||
vladimir = cls(
|
||||
|
@ -74,8 +73,9 @@ class Vladimir(Ursula):
|
|||
network_middleware=cls.network_middleware,
|
||||
checksum_address=cls.fraud_address,
|
||||
operator_address=cls.fraud_address,
|
||||
signer=Web3Signer(blockchain.client),
|
||||
eth_provider_uri=blockchain.eth_provider_uri,
|
||||
signer=Web3Signer(eth_blockchain.client),
|
||||
eth_endpoint=eth_blockchain.endpoint,
|
||||
polygon_endpoint=polygon_blockchain.endpoint,
|
||||
pre_payment_method=bogus_pre_payment_method,
|
||||
)
|
||||
|
||||
|
|
|
@ -126,13 +126,13 @@ def handle_invalid_configuration_file(emitter: StdoutEmitter,
|
|||
|
||||
|
||||
def collect_operator_ip_address(
|
||||
emitter: StdoutEmitter, network: str, provider_uri: str, force: bool = False
|
||||
emitter: StdoutEmitter, domain: str, eth_endpoint: str, force: bool = False
|
||||
) -> str:
|
||||
# From node swarm
|
||||
try:
|
||||
message = "Detecting external IP address automatically"
|
||||
emitter.message(message, verbosity=2)
|
||||
ip = determine_external_ip_address(network=network, provider_uri=provider_uri)
|
||||
ip = determine_external_ip_address(domain=domain, eth_endpoint=eth_endpoint)
|
||||
except UnknownIPAddress:
|
||||
if force:
|
||||
raise
|
||||
|
@ -157,9 +157,9 @@ def perform_startup_ip_check(emitter: StdoutEmitter, ursula: Ursula, force: bool
|
|||
"""
|
||||
try:
|
||||
external_ip = determine_external_ip_address(
|
||||
network=ursula.domain,
|
||||
domain=ursula.domain,
|
||||
known_nodes=ursula.known_nodes,
|
||||
provider_uri=ursula.eth_provider_uri,
|
||||
eth_endpoint=ursula.eth_endpoint,
|
||||
)
|
||||
except UnknownIPAddress:
|
||||
message = 'Cannot automatically determine external IP address'
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import Optional, Type
|
||||
|
@ -8,22 +6,20 @@ import click
|
|||
from tabulate import tabulate
|
||||
from web3.main import Web3
|
||||
|
||||
from nucypher.blockchain.eth.agents import ContractAgency, NucypherTokenAgent
|
||||
from nucypher.blockchain.eth.domains import TACoDomain
|
||||
from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory
|
||||
from nucypher.blockchain.eth.networks import NetworksInventory
|
||||
from nucypher.blockchain.eth.registry import (
|
||||
ContractRegistry,
|
||||
)
|
||||
from nucypher.blockchain.eth.signers.base import Signer
|
||||
from nucypher.blockchain.eth.token import NU
|
||||
from nucypher.cli.actions.configure import get_config_filepaths
|
||||
from nucypher.cli.literature import (
|
||||
DEFAULT_TO_LONE_CONFIG_FILE,
|
||||
GENERIC_SELECT_ACCOUNT,
|
||||
IGNORE_OLD_CONFIGURATION,
|
||||
NO_ACCOUNTS,
|
||||
NO_CONFIGURATIONS_ON_DISK,
|
||||
NO_ETH_ACCOUNTS,
|
||||
SELECT_NETWORK,
|
||||
SELECT_DOMAIN,
|
||||
SELECTED_ACCOUNT,
|
||||
)
|
||||
from nucypher.config.base import CharacterConfiguration
|
||||
|
@ -36,53 +32,56 @@ from nucypher.utilities.emitters import StdoutEmitter
|
|||
|
||||
def select_client_account(
|
||||
emitter,
|
||||
eth_provider_uri: str = None,
|
||||
polygon_endpoint: str = None,
|
||||
signer: Signer = None,
|
||||
signer_uri: str = None,
|
||||
prompt: str = None,
|
||||
default: int = 0,
|
||||
registry: ContractRegistry = None,
|
||||
show_eth_balance: bool = False,
|
||||
show_nu_balance: bool = False,
|
||||
show_matic_balance: bool = False,
|
||||
show_staking: bool = False,
|
||||
network: str = None,
|
||||
domain: str = None,
|
||||
poa: bool = None,
|
||||
) -> str:
|
||||
"""
|
||||
Interactively select an ethereum wallet account from a table of nucypher account metadata.
|
||||
Interactively select an ethereum wallet account from a table of account metadata.
|
||||
|
||||
Note: Showing ETH and/or NU balances, causes an eager blockchain connection.
|
||||
Note: Showing MATIC balance causes an eager blockchain connection.
|
||||
"""
|
||||
|
||||
if signer and signer_uri:
|
||||
raise ValueError('Pass either signer or signer_uri but not both.')
|
||||
|
||||
if not any((eth_provider_uri, signer_uri, signer)):
|
||||
if not any((polygon_endpoint, signer_uri, signer)):
|
||||
raise ValueError("At least a provider URI, signer URI or signer must be provided to select an account")
|
||||
|
||||
if eth_provider_uri:
|
||||
if polygon_endpoint:
|
||||
# Connect to the blockchain in order to select an account
|
||||
if not BlockchainInterfaceFactory.is_interface_initialized(eth_provider_uri=eth_provider_uri):
|
||||
BlockchainInterfaceFactory.initialize_interface(eth_provider_uri=eth_provider_uri, poa=poa, emitter=emitter)
|
||||
if not BlockchainInterfaceFactory.is_interface_initialized(
|
||||
endpoint=polygon_endpoint
|
||||
):
|
||||
BlockchainInterfaceFactory.initialize_interface(
|
||||
endpoint=polygon_endpoint, poa=poa, emitter=emitter
|
||||
)
|
||||
if not signer_uri:
|
||||
signer_uri = eth_provider_uri
|
||||
signer_uri = polygon_endpoint
|
||||
|
||||
blockchain = BlockchainInterfaceFactory.get_interface(eth_provider_uri=eth_provider_uri)
|
||||
blockchain = BlockchainInterfaceFactory.get_interface(endpoint=polygon_endpoint)
|
||||
|
||||
if signer_uri and not signer:
|
||||
testnet = network != NetworksInventory.MAINNET
|
||||
testnet = domain != TACoDomain.MAINNET.name
|
||||
signer = Signer.from_signer_uri(signer_uri, testnet=testnet)
|
||||
|
||||
# Display accounts info
|
||||
if show_nu_balance or show_staking: # Lazy registry fetching
|
||||
if show_staking: # Lazy registry fetching
|
||||
if not registry:
|
||||
if not network:
|
||||
raise ValueError("Pass network name or registry; Got neither.")
|
||||
registry = ContractRegistry.from_latest_publication(domain=network)
|
||||
if not domain:
|
||||
raise ValueError("Pass domain name or registry; Got neither.")
|
||||
registry = ContractRegistry.from_latest_publication(domain=domain)
|
||||
|
||||
enumerated_accounts = dict(enumerate(signer.accounts))
|
||||
if len(enumerated_accounts) < 1:
|
||||
emitter.echo(NO_ETH_ACCOUNTS, color='red', bold=True)
|
||||
emitter.echo(NO_ACCOUNTS, color="red", bold=True)
|
||||
raise click.Abort()
|
||||
elif len(enumerated_accounts) == 1:
|
||||
# There are no choices if there is only one available address.
|
||||
|
@ -90,23 +89,17 @@ def select_client_account(
|
|||
|
||||
# Display account info
|
||||
headers = ['Account']
|
||||
if show_eth_balance:
|
||||
headers.append('ETH')
|
||||
if show_nu_balance:
|
||||
headers.append('NU')
|
||||
if show_matic_balance:
|
||||
headers.append("MATIC")
|
||||
|
||||
rows = list()
|
||||
for index, account in enumerated_accounts.items():
|
||||
row = [account]
|
||||
if show_eth_balance:
|
||||
ether_balance = Web3.from_wei(blockchain.client.get_balance(account), 'ether')
|
||||
row.append(f'{ether_balance} ETH')
|
||||
if show_nu_balance:
|
||||
token_agent = ContractAgency.get_agent(
|
||||
NucypherTokenAgent, registry=registry, provider_uri=eth_provider_uri
|
||||
if show_matic_balance:
|
||||
matic_balance = Web3.from_wei(
|
||||
blockchain.client.get_balance(account), "ether"
|
||||
)
|
||||
token_balance = NU.from_units(token_agent.get_balance(account, registry))
|
||||
row.append(token_balance)
|
||||
row.append(f"{matic_balance} MATIC")
|
||||
rows.append(row)
|
||||
emitter.echo(tabulate(rows, headers=headers, showindex='always'))
|
||||
|
||||
|
@ -120,24 +113,19 @@ def select_client_account(
|
|||
return chosen_account
|
||||
|
||||
|
||||
def select_network(emitter: StdoutEmitter, network_type: str, message: Optional[str] = None) -> str:
|
||||
"""Interactively select a network from nucypher networks inventory list"""
|
||||
def select_domain(emitter: StdoutEmitter, message: Optional[str] = None) -> str:
|
||||
"""Interactively select a domain from TACo domain inventory list"""
|
||||
emitter.message(message=message or str(), color="yellow")
|
||||
if network_type == NetworksInventory.ETH:
|
||||
network_list = NetworksInventory.ETH_NETWORKS
|
||||
elif network_type == NetworksInventory.POLYGON:
|
||||
network_list = NetworksInventory.POLY_NETWORKS
|
||||
else:
|
||||
raise(ValueError("Network type must be either 'eth' or 'polygon'"))
|
||||
rows = [[n] for n in network_list]
|
||||
domain_list = TACoDomain.SUPPORTED_DOMAIN_NAMES
|
||||
rows = [[n] for n in domain_list]
|
||||
emitter.echo(tabulate(rows, showindex="always"))
|
||||
choice = click.prompt(
|
||||
SELECT_NETWORK,
|
||||
SELECT_DOMAIN,
|
||||
default=0,
|
||||
type=click.IntRange(0, len(rows) - 1),
|
||||
)
|
||||
network = network_list[choice]
|
||||
return network
|
||||
domain = domain_list[choice]
|
||||
return domain
|
||||
|
||||
|
||||
def select_config_file(emitter: StdoutEmitter,
|
||||
|
|
|
@ -11,7 +11,7 @@ from nucypher.blockchain.eth.constants import (
|
|||
AVERAGE_BLOCK_TIME_IN_SECONDS,
|
||||
TACO_CONTRACT_NAMES,
|
||||
)
|
||||
from nucypher.blockchain.eth.networks import NetworksInventory
|
||||
from nucypher.blockchain.eth.domains import TACoDomain
|
||||
from nucypher.cli.config import group_general_config
|
||||
from nucypher.cli.options import (
|
||||
group_options,
|
||||
|
@ -30,19 +30,19 @@ from nucypher.cli.utils import (
|
|||
)
|
||||
from nucypher.utilities.events import generate_events_csv_filepath
|
||||
|
||||
option_provider_uri = click.option(
|
||||
"--provider-uri",
|
||||
"provider_uri",
|
||||
option_blockchain_endpoint = click.option(
|
||||
"--blockchain-endpoint",
|
||||
"blockchain_endpoint",
|
||||
help="Blockchain provider's URI i.e. 'file:///path/to/geth.ipc'",
|
||||
type=click.STRING,
|
||||
required=True,
|
||||
)
|
||||
|
||||
option_network = click.option(
|
||||
"--network",
|
||||
help="TACo Network",
|
||||
option_domain = click.option(
|
||||
"--domain",
|
||||
help="TACo Domain",
|
||||
type=click.STRING,
|
||||
default=click.Choice(NetworksInventory.NETWORKS),
|
||||
default=click.Choice(TACoDomain.SUPPORTED_DOMAIN_NAMES),
|
||||
required=True,
|
||||
)
|
||||
|
||||
|
@ -50,19 +50,19 @@ option_network = click.option(
|
|||
class RegistryOptions:
|
||||
__option_name__ = "registry_options"
|
||||
|
||||
def __init__(self, provider_uri, poa, registry_filepath, light, network):
|
||||
self.provider_uri = provider_uri
|
||||
def __init__(self, blockchain_endpoint, poa, registry_filepath, light, domain):
|
||||
self.blockchain_endpoint = blockchain_endpoint
|
||||
self.poa = poa
|
||||
self.registry_filepath = registry_filepath
|
||||
self.light = light
|
||||
self.network = network
|
||||
self.domain = domain
|
||||
|
||||
def setup(self, general_config) -> tuple:
|
||||
emitter = setup_emitter(general_config)
|
||||
registry = get_registry(
|
||||
network=self.network, registry_filepath=self.registry_filepath
|
||||
domain=self.domain, registry_filepath=self.registry_filepath
|
||||
)
|
||||
return emitter, registry, self.provider_uri
|
||||
return emitter, registry, self.blockchain_endpoint
|
||||
|
||||
|
||||
group_registry_options = group_options(
|
||||
|
@ -70,8 +70,8 @@ group_registry_options = group_options(
|
|||
poa=option_poa,
|
||||
light=option_light,
|
||||
registry_filepath=option_registry_filepath,
|
||||
network=option_network,
|
||||
provider_uri=option_provider_uri,
|
||||
domain=option_domain,
|
||||
blockchain_endpoint=option_blockchain_endpoint,
|
||||
)
|
||||
|
||||
option_csv = click.option(
|
||||
|
@ -117,11 +117,11 @@ def taco():
|
|||
@group_general_config
|
||||
def application_info(general_config, registry_options):
|
||||
"""Overall information for the TACo Application."""
|
||||
emitter, registry, provider_uri = registry_options.setup(
|
||||
emitter, registry, blockchain_endpoint = registry_options.setup(
|
||||
general_config=general_config
|
||||
)
|
||||
paint_application_contract_status(
|
||||
emitter=emitter, registry=registry, provider_uri=provider_uri
|
||||
emitter=emitter, registry=registry, eth_endpoint=blockchain_endpoint
|
||||
)
|
||||
|
||||
|
||||
|
@ -130,11 +130,11 @@ def application_info(general_config, registry_options):
|
|||
@group_general_config
|
||||
def active_providers(general_config, registry_options):
|
||||
"""List of active stakers for the TACo Application"""
|
||||
emitter, registry, provider_uri = registry_options.setup(
|
||||
emitter, registry, blockchain_endpoint = registry_options.setup(
|
||||
general_config=general_config
|
||||
)
|
||||
application_agent = ContractAgency.get_agent(
|
||||
TACoApplicationAgent, registry=registry, provider_uri=provider_uri
|
||||
TACoApplicationAgent, registry=registry, blockchain_endpoint=blockchain_endpoint
|
||||
)
|
||||
(
|
||||
total_staked,
|
||||
|
@ -194,12 +194,14 @@ def events(
|
|||
),
|
||||
)
|
||||
|
||||
emitter, registry, provider_uri = registry_options.setup(
|
||||
emitter, registry, blockchain_endpoint = registry_options.setup(
|
||||
general_config=general_config
|
||||
)
|
||||
|
||||
contract_agent = ContractAgency.get_agent_by_contract_name(
|
||||
contract_name=contract_name, registry=registry, provider_uri=provider_uri
|
||||
contract_name=contract_name,
|
||||
registry=registry,
|
||||
blockchain_endpoint=blockchain_endpoint,
|
||||
)
|
||||
|
||||
if from_block is None:
|
||||
|
|
|
@ -2,7 +2,6 @@ from pathlib import Path
|
|||
|
||||
import click
|
||||
|
||||
from nucypher.blockchain.eth.networks import NetworksInventory
|
||||
from nucypher.cli.actions.auth import (
|
||||
get_client_password,
|
||||
get_nucypher_password,
|
||||
|
@ -15,26 +14,28 @@ from nucypher.cli.actions.configure import (
|
|||
handle_missing_configuration_file,
|
||||
perform_startup_ip_check,
|
||||
)
|
||||
from nucypher.cli.actions.configure import forget as forget_nodes
|
||||
from nucypher.cli.actions.configure import (
|
||||
forget as forget_nodes,
|
||||
)
|
||||
from nucypher.cli.actions.select import (
|
||||
select_client_account,
|
||||
select_config_file,
|
||||
select_network,
|
||||
select_domain,
|
||||
)
|
||||
from nucypher.cli.config import group_general_config
|
||||
from nucypher.cli.literature import (
|
||||
DEVELOPMENT_MODE_WARNING,
|
||||
FORCE_MODE_WARNING,
|
||||
SELECT_OPERATOR_ACCOUNT,
|
||||
SELECT_PRE_PAYMENT_NETWORK,
|
||||
)
|
||||
from nucypher.cli.options import (
|
||||
group_options,
|
||||
option_config_file,
|
||||
option_config_root,
|
||||
option_dev,
|
||||
option_domain,
|
||||
option_dry_run,
|
||||
option_eth_provider_uri,
|
||||
option_eth_endpoint,
|
||||
option_force,
|
||||
option_gas_strategy,
|
||||
option_key_material,
|
||||
|
@ -42,12 +43,9 @@ from nucypher.cli.options import (
|
|||
option_lonely,
|
||||
option_max_gas_price,
|
||||
option_min_stake,
|
||||
option_network,
|
||||
option_poa,
|
||||
option_policy_registry_filepath,
|
||||
option_polygon_endpoint,
|
||||
option_pre_payment_method,
|
||||
option_pre_payment_network,
|
||||
option_pre_payment_provider,
|
||||
option_registry_filepath,
|
||||
option_signer_uri,
|
||||
option_teacher_uri,
|
||||
|
@ -74,13 +72,12 @@ class UrsulaConfigOptions:
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
eth_provider_uri: str,
|
||||
eth_endpoint: str,
|
||||
operator_address: str,
|
||||
rest_host: str,
|
||||
rest_port: int,
|
||||
network: str,
|
||||
domain: str,
|
||||
registry_filepath: Path,
|
||||
policy_registry_filepath: Path,
|
||||
dev: bool,
|
||||
poa: bool,
|
||||
light: bool,
|
||||
|
@ -88,19 +85,17 @@ class UrsulaConfigOptions:
|
|||
max_gas_price: int, # gwei
|
||||
signer_uri: str,
|
||||
lonely: bool,
|
||||
polygon_endpoint: str,
|
||||
pre_payment_method: str,
|
||||
pre_payment_provider: str,
|
||||
pre_payment_network: str,
|
||||
):
|
||||
|
||||
self.eth_provider_uri = eth_provider_uri
|
||||
self.eth_endpoint = eth_endpoint
|
||||
self.signer_uri = signer_uri
|
||||
self.operator_address = operator_address
|
||||
self.rest_host = rest_host
|
||||
self.rest_port = rest_port # FIXME: not used in generate()
|
||||
self.domain = network
|
||||
self.domain = domain
|
||||
self.registry_filepath = registry_filepath
|
||||
self.policy_registry_filepath = policy_registry_filepath
|
||||
self.dev = dev
|
||||
self.poa = poa
|
||||
self.light = light
|
||||
|
@ -108,8 +103,7 @@ class UrsulaConfigOptions:
|
|||
self.max_gas_price = max_gas_price
|
||||
self.lonely = lonely
|
||||
self.pre_payment_method = pre_payment_method
|
||||
self.pre_payment_provider = pre_payment_provider
|
||||
self.pre_payment_network = pre_payment_network
|
||||
self.polygon_endpoint = polygon_endpoint
|
||||
|
||||
def create_config(self, emitter, config_file):
|
||||
if self.dev:
|
||||
|
@ -120,8 +114,7 @@ class UrsulaConfigOptions:
|
|||
poa=self.poa,
|
||||
light=self.light,
|
||||
registry_filepath=self.registry_filepath,
|
||||
policy_registry_filepath=self.policy_registry_filepath,
|
||||
eth_provider_uri=self.eth_provider_uri,
|
||||
eth_endpoint=self.eth_endpoint,
|
||||
signer_uri=self.signer_uri,
|
||||
gas_strategy=self.gas_strategy,
|
||||
max_gas_price=self.max_gas_price,
|
||||
|
@ -129,8 +122,7 @@ class UrsulaConfigOptions:
|
|||
rest_host=self.rest_host,
|
||||
rest_port=self.rest_port,
|
||||
pre_payment_method=self.pre_payment_method,
|
||||
pre_payment_provider=self.pre_payment_provider,
|
||||
pre_payment_network=self.pre_payment_network,
|
||||
polygon_endpoint=self.polygon_endpoint,
|
||||
)
|
||||
else:
|
||||
if not config_file:
|
||||
|
@ -143,8 +135,7 @@ class UrsulaConfigOptions:
|
|||
filepath=config_file,
|
||||
domain=self.domain,
|
||||
registry_filepath=self.registry_filepath,
|
||||
policy_registry_filepath=self.policy_registry_filepath,
|
||||
eth_provider_uri=self.eth_provider_uri,
|
||||
eth_endpoint=self.eth_endpoint,
|
||||
signer_uri=self.signer_uri,
|
||||
gas_strategy=self.gas_strategy,
|
||||
max_gas_price=self.max_gas_price,
|
||||
|
@ -153,8 +144,7 @@ class UrsulaConfigOptions:
|
|||
poa=self.poa,
|
||||
light=self.light,
|
||||
pre_payment_method=self.pre_payment_method,
|
||||
pre_payment_provider=self.pre_payment_provider,
|
||||
pre_payment_network=self.pre_payment_network,
|
||||
polygon_endpoint=self.polygon_endpoint,
|
||||
)
|
||||
except FileNotFoundError:
|
||||
return handle_missing_configuration_file(character_config_class=UrsulaConfiguration, config_file=config_file)
|
||||
|
@ -175,7 +165,7 @@ class UrsulaConfigOptions:
|
|||
self.operator_address = select_client_account(
|
||||
emitter=emitter,
|
||||
prompt=prompt,
|
||||
eth_provider_uri=self.eth_provider_uri,
|
||||
polygon_endpoint=self.polygon_endpoint,
|
||||
signer_uri=self.signer_uri,
|
||||
)
|
||||
|
||||
|
@ -183,9 +173,9 @@ class UrsulaConfigOptions:
|
|||
if not self.rest_host:
|
||||
self.rest_host = collect_operator_ip_address(
|
||||
emitter,
|
||||
network=self.domain,
|
||||
domain=self.domain,
|
||||
force=force,
|
||||
provider_uri=self.eth_provider_uri,
|
||||
eth_endpoint=self.eth_endpoint,
|
||||
)
|
||||
|
||||
return UrsulaConfiguration.generate(
|
||||
|
@ -197,16 +187,14 @@ class UrsulaConfigOptions:
|
|||
domain=self.domain,
|
||||
operator_address=self.operator_address,
|
||||
registry_filepath=self.registry_filepath,
|
||||
policy_registry_filepath=self.policy_registry_filepath,
|
||||
eth_provider_uri=self.eth_provider_uri,
|
||||
eth_endpoint=self.eth_endpoint,
|
||||
signer_uri=self.signer_uri,
|
||||
gas_strategy=self.gas_strategy,
|
||||
max_gas_price=self.max_gas_price,
|
||||
poa=self.poa,
|
||||
light=self.light,
|
||||
pre_payment_method=self.pre_payment_method,
|
||||
pre_payment_provider=self.pre_payment_provider,
|
||||
pre_payment_network=self.pre_payment_network,
|
||||
polygon_endpoint=self.polygon_endpoint,
|
||||
)
|
||||
|
||||
def get_updates(self) -> dict:
|
||||
|
@ -216,16 +204,14 @@ class UrsulaConfigOptions:
|
|||
domain=self.domain,
|
||||
operator_address=self.operator_address,
|
||||
registry_filepath=self.registry_filepath,
|
||||
policy_registry_filepath=self.policy_registry_filepath,
|
||||
eth_provider_uri=self.eth_provider_uri,
|
||||
eth_endpoint=self.eth_endpoint,
|
||||
signer_uri=self.signer_uri,
|
||||
gas_strategy=self.gas_strategy,
|
||||
max_gas_price=self.max_gas_price,
|
||||
poa=self.poa,
|
||||
light=self.light,
|
||||
pre_payment_method=self.pre_payment_method,
|
||||
pre_payment_provider=self.pre_payment_provider,
|
||||
pre_payment_network=self.pre_payment_network,
|
||||
polygon_endpoint=self.polygon_endpoint,
|
||||
)
|
||||
# Depends on defaults being set on Configuration classes, filtrates None values
|
||||
updates = {k: v for k, v in payload.items() if v is not None}
|
||||
|
@ -235,7 +221,7 @@ class UrsulaConfigOptions:
|
|||
group_config_options = group_options(
|
||||
# NOTE: Don't set defaults here or they will be applied to config updates. Use the Config API.
|
||||
UrsulaConfigOptions,
|
||||
eth_provider_uri=option_eth_provider_uri(),
|
||||
eth_endpoint=option_eth_endpoint(),
|
||||
signer_uri=option_signer_uri,
|
||||
gas_strategy=option_gas_strategy,
|
||||
max_gas_price=option_max_gas_price,
|
||||
|
@ -254,15 +240,13 @@ group_config_options = group_options(
|
|||
help="The host port to run Ursula network services on",
|
||||
type=NETWORK_PORT,
|
||||
),
|
||||
network=option_network(),
|
||||
domain=option_domain(),
|
||||
registry_filepath=option_registry_filepath,
|
||||
policy_registry_filepath=option_policy_registry_filepath,
|
||||
poa=option_poa,
|
||||
light=option_light,
|
||||
dev=option_dev,
|
||||
lonely=option_lonely,
|
||||
pre_payment_provider=option_pre_payment_provider,
|
||||
pre_payment_network=option_pre_payment_network,
|
||||
polygon_endpoint=option_polygon_endpoint,
|
||||
pre_payment_method=option_pre_payment_method,
|
||||
)
|
||||
|
||||
|
@ -290,7 +274,7 @@ class UrsulaCharacterOptions:
|
|||
URSULA = make_cli_character(
|
||||
character_config=ursula_config,
|
||||
emitter=emitter,
|
||||
provider_uri=ursula_config.eth_provider_uri,
|
||||
eth_endpoint=ursula_config.eth_endpoint,
|
||||
min_stake=self.min_stake,
|
||||
teacher_uri=self.teacher_uri,
|
||||
unlock_keystore=not self.config_options.dev,
|
||||
|
@ -333,32 +317,25 @@ def init(general_config, config_options, force, config_root, key_material):
|
|||
_pre_launch_warnings(emitter, dev=None, force=force)
|
||||
if not config_root:
|
||||
config_root = general_config.config_root
|
||||
if not config_options.eth_provider_uri:
|
||||
if not config_options.eth_endpoint:
|
||||
raise click.BadOptionUsage(
|
||||
"--eth-provider",
|
||||
"--eth-endpoint",
|
||||
message=click.style(
|
||||
"--eth-provider is required to initialize a new ursula.", fg="red"
|
||||
"--eth-endpoint is required to initialize a new ursula.", fg="red"
|
||||
),
|
||||
)
|
||||
if not config_options.pre_payment_provider:
|
||||
if not config_options.polygon_endpoint:
|
||||
raise click.BadOptionUsage(
|
||||
"--pre-payment-provider",
|
||||
"--polygon-endpoint",
|
||||
message=click.style(
|
||||
"--pre-payment-provider is required to initialize a new ursula.",
|
||||
"--polygon-endpoint is required to initialize a new ursula.",
|
||||
fg="red",
|
||||
),
|
||||
)
|
||||
if not config_options.domain:
|
||||
config_options.domain = select_network(
|
||||
config_options.domain = select_domain(
|
||||
emitter,
|
||||
message="Select Staking Network",
|
||||
network_type=NetworksInventory.ETH,
|
||||
)
|
||||
if not config_options.pre_payment_network:
|
||||
config_options.pre_payment_network = select_network(
|
||||
emitter,
|
||||
message=SELECT_PRE_PAYMENT_NETWORK,
|
||||
network_type=NetworksInventory.POLYGON,
|
||||
message="Select TACo Domain",
|
||||
)
|
||||
ursula_config = config_options.generate_config(
|
||||
emitter=emitter, config_root=config_root, force=force, key_material=key_material
|
||||
|
@ -496,9 +473,9 @@ def config(general_config, config_options, config_file, force, action):
|
|||
if action == "ip-address":
|
||||
rest_host = collect_operator_ip_address(
|
||||
emitter=emitter,
|
||||
network=config_options.domain,
|
||||
domain=config_options.domain,
|
||||
force=force,
|
||||
provider_uri=config_options.eth_provider_uri,
|
||||
eth_endpoint=config_options.eth_endpoint,
|
||||
)
|
||||
config_options.rest_host = rest_host
|
||||
if action == "migrate":
|
||||
|
|
|
@ -43,9 +43,7 @@ nucypher {init_command}
|
|||
"""
|
||||
|
||||
|
||||
SELECT_NETWORK = "Select Network"
|
||||
|
||||
SELECT_PRE_PAYMENT_NETWORK = "Select PRE Payment Network"
|
||||
SELECT_DOMAIN = "Select TACo Domain"
|
||||
|
||||
NO_CONFIGURATIONS_ON_DISK = "No {name} configurations found. Run 'nucypher {command} init' then try again."
|
||||
|
||||
|
@ -55,7 +53,7 @@ INVALID_JSON_IN_CONFIGURATION_WARNING = "Invalid JSON in Configuration File at {
|
|||
|
||||
INVALID_CONFIGURATION_FILE_WARNING = "Invalid Configuration at {filepath}."
|
||||
|
||||
NO_ETH_ACCOUNTS = "No ETH accounts were found."
|
||||
NO_ACCOUNTS = "No accounts were found."
|
||||
|
||||
GENERIC_SELECT_ACCOUNT = "Select index of account"
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ from nucypher.cli.types import (
|
|||
NETWORK_PORT,
|
||||
PRE_PAYMENT_METHOD_CHOICES,
|
||||
STAKED_TOKENS_RANGE,
|
||||
NuCypherNetworkName,
|
||||
NuCypherDomainName,
|
||||
)
|
||||
from nucypher.utilities.logging import Logger
|
||||
|
||||
|
@ -79,19 +79,13 @@ option_parameters = click.option(
|
|||
help="Filepath to a JSON file containing additional parameters",
|
||||
type=EXISTING_READABLE_FILE,
|
||||
)
|
||||
option_pre_payment_provider = click.option(
|
||||
"--pre-payment-provider",
|
||||
"pre_payment_provider",
|
||||
option_polygon_endpoint = click.option(
|
||||
"--polygon-endpoint",
|
||||
"polygon_endpoint",
|
||||
help="Connection URL for PRE payment method",
|
||||
type=click.STRING,
|
||||
required=False,
|
||||
)
|
||||
option_pre_payment_network = click.option(
|
||||
"--pre-payment-network",
|
||||
help="PRE payment network name",
|
||||
type=click.STRING,
|
||||
required=False,
|
||||
) # TODO: Choices
|
||||
option_pre_payment_method = click.option(
|
||||
"--pre-payment-method",
|
||||
help="PRE payment method name",
|
||||
|
@ -106,11 +100,6 @@ option_registry_filepath = click.option(
|
|||
help="Custom contract registry filepath",
|
||||
type=EXISTING_READABLE_FILE,
|
||||
)
|
||||
option_policy_registry_filepath = click.option(
|
||||
"--policy-registry-filepath",
|
||||
help="Custom contract registry filepath for policies",
|
||||
type=EXISTING_READABLE_FILE,
|
||||
)
|
||||
option_signer_uri = click.option("--signer", "signer_uri", "-S", default=None, type=str)
|
||||
option_staking_provider = click.option(
|
||||
"--staking-provider",
|
||||
|
@ -180,13 +169,15 @@ def option_message_kit(required: bool = False, multiple: bool = False):
|
|||
required=required)
|
||||
|
||||
|
||||
def option_network(required: bool = False,
|
||||
default: str = None, # NetworksInventory.DEFAULT is not a good global default (2214)
|
||||
validate: bool = False):
|
||||
def option_domain(
|
||||
required: bool = False,
|
||||
default: str = None, # nucypher.blockchain.eth.domains.DEFAULT.name is not a good global default (#2214)
|
||||
validate: bool = False,
|
||||
):
|
||||
return click.option(
|
||||
'--network',
|
||||
help="NuCypher Network/Domain Name",
|
||||
type=NuCypherNetworkName(validate=validate),
|
||||
"--domain",
|
||||
help="TACo Domain Name",
|
||||
type=NuCypherDomainName(validate=validate),
|
||||
required=required,
|
||||
default=default)
|
||||
|
||||
|
@ -199,9 +190,10 @@ def option_policy_encrypting_key(required: bool = False):
|
|||
required=required)
|
||||
|
||||
|
||||
def option_eth_provider_uri(default=None, required: bool = False):
|
||||
def option_eth_endpoint(default=None, required: bool = False):
|
||||
return click.option(
|
||||
'--eth-provider', 'eth_provider_uri',
|
||||
"--eth-endpoint",
|
||||
"eth_endpoint",
|
||||
help="Blockchain provider's URI i.e. 'file:///path/to/geth.ipc'",
|
||||
type=click.STRING,
|
||||
required=required,
|
||||
|
|
|
@ -4,9 +4,9 @@ from nucypher.blockchain.eth.agents import (
|
|||
)
|
||||
|
||||
|
||||
def paint_application_contract_status(emitter, registry, provider_uri):
|
||||
def paint_application_contract_status(emitter, registry, eth_endpoint):
|
||||
application_agent = ContractAgency.get_agent(
|
||||
TACoApplicationAgent, registry=registry, provider_uri=provider_uri
|
||||
TACoApplicationAgent, registry=registry, blockchain_endpoint=eth_endpoint
|
||||
)
|
||||
blockchain = application_agent.blockchain
|
||||
|
||||
|
|
|
@ -5,9 +5,15 @@ from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory
|
|||
from nucypher.blockchain.eth.utils import etherscan_url
|
||||
|
||||
|
||||
def paint_receipt_summary(emitter, receipt, chain_name: str = None, transaction_type=None, eth_provider_uri: str = None):
|
||||
tx_hash = receipt['transactionHash'].hex()
|
||||
emitter.echo("OK", color='green', nl=False, bold=True)
|
||||
def paint_receipt_summary(
|
||||
emitter,
|
||||
receipt,
|
||||
chain_name: str = None,
|
||||
transaction_type=None,
|
||||
blockchain_endpoint: str = None,
|
||||
):
|
||||
tx_hash = receipt["transactionHash"].hex()
|
||||
emitter.echo("OK", color="green", nl=False, bold=True)
|
||||
if transaction_type:
|
||||
emitter.echo(f" | {transaction_type} | {tx_hash}", color='yellow', nl=False)
|
||||
else:
|
||||
|
@ -16,7 +22,9 @@ def paint_receipt_summary(emitter, receipt, chain_name: str = None, transaction_
|
|||
emitter.echo(f"Block #{receipt['blockNumber']} | {receipt['blockHash'].hex()}")
|
||||
|
||||
if not chain_name:
|
||||
blockchain = BlockchainInterfaceFactory.get_interface(eth_provider_uri=eth_provider_uri)
|
||||
blockchain = BlockchainInterfaceFactory.get_interface(
|
||||
endpoint=blockchain_endpoint
|
||||
)
|
||||
chain_name = blockchain.client.chain_name
|
||||
try:
|
||||
url = etherscan_url(item=tx_hash, network=chain_name)
|
||||
|
|
|
@ -10,7 +10,7 @@ from cryptography.exceptions import InternalError
|
|||
from eth_utils import to_checksum_address
|
||||
from nucypher_core.umbral import PublicKey
|
||||
|
||||
from nucypher.blockchain.eth.networks import NetworksInventory
|
||||
from nucypher.blockchain.eth.domains import TACoDomain
|
||||
from nucypher.blockchain.eth.token import TToken
|
||||
from nucypher.policy.payment import PRE_PAYMENT_METHODS
|
||||
from nucypher.utilities.networking import InvalidOperatorIP, validate_operator_ip
|
||||
|
@ -88,21 +88,21 @@ class DecimalRange(DecimalType):
|
|||
return rv
|
||||
|
||||
|
||||
class NuCypherNetworkName(click.ParamType):
|
||||
name = 'nucypher_network_name'
|
||||
class NuCypherDomainName(click.ParamType):
|
||||
name = "nucypher_domain_name"
|
||||
|
||||
def __init__(self, validate: bool = True):
|
||||
self.validate = bool(validate)
|
||||
|
||||
def convert(self, value, param, ctx):
|
||||
if self.validate:
|
||||
network = str(value).lower()
|
||||
if network not in NetworksInventory.ETH_NETWORKS:
|
||||
domain = str(value).lower()
|
||||
if domain not in TACoDomain.SUPPORTED_DOMAIN_NAMES:
|
||||
self.fail(
|
||||
f"'{value}' is not a recognized network. Valid options are: {list(NetworksInventory.ETH_NETWORKS)}"
|
||||
f"'{value}' is not a recognized domain. Valid options are: {list(TACoDomain.SUPPORTED_DOMAIN_NAMES)}"
|
||||
)
|
||||
else:
|
||||
return network
|
||||
return domain
|
||||
else:
|
||||
return value
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ from nucypher.blockchain.eth.interfaces import (
|
|||
)
|
||||
from nucypher.blockchain.eth.registry import (
|
||||
ContractRegistry,
|
||||
LocalRegistrySource,
|
||||
)
|
||||
from nucypher.characters.base import Character
|
||||
from nucypher.cli.actions.auth import (
|
||||
|
@ -45,7 +46,7 @@ def setup_emitter(general_config, banner: str = None) -> StdoutEmitter:
|
|||
def make_cli_character(
|
||||
character_config,
|
||||
emitter,
|
||||
provider_uri: str,
|
||||
eth_endpoint: str,
|
||||
unlock_keystore: bool = True,
|
||||
unlock_signer: bool = True,
|
||||
teacher_uri: str = None,
|
||||
|
@ -82,14 +83,14 @@ def make_cli_character(
|
|||
min_stake=min_stake,
|
||||
network_middleware=character_config.network_middleware,
|
||||
registry=character_config.registry,
|
||||
provider_uri=provider_uri,
|
||||
eth_endpoint=eth_endpoint,
|
||||
)
|
||||
sage_nodes.append(maybe_sage_node)
|
||||
|
||||
CHARACTER = character_config(
|
||||
known_nodes=sage_nodes,
|
||||
network_middleware=character_config.network_middleware,
|
||||
eth_provider_uri=provider_uri,
|
||||
eth_endpoint=eth_endpoint,
|
||||
**config_args,
|
||||
)
|
||||
|
||||
|
@ -102,28 +103,34 @@ def make_cli_character(
|
|||
|
||||
|
||||
def get_registry(
|
||||
network: str, registry_filepath: Optional[Path] = None
|
||||
domain: str, registry_filepath: Optional[Path] = None
|
||||
) -> ContractRegistry:
|
||||
if registry_filepath:
|
||||
registry = ContractRegistry(filepath=registry_filepath)
|
||||
source = LocalRegistrySource(filepath=registry_filepath)
|
||||
registry = ContractRegistry(source=source)
|
||||
else:
|
||||
registry = ContractRegistry.from_latest_publication(domain=network)
|
||||
registry = ContractRegistry.from_latest_publication(domain=domain)
|
||||
return registry
|
||||
|
||||
|
||||
def connect_to_blockchain(emitter: StdoutEmitter,
|
||||
eth_provider_uri: str,
|
||||
debug: bool = False,
|
||||
light: bool = False
|
||||
) -> BlockchainInterface:
|
||||
def connect_to_blockchain(
|
||||
emitter: StdoutEmitter,
|
||||
blockchain_endpoint: str,
|
||||
debug: bool = False,
|
||||
light: bool = False,
|
||||
) -> BlockchainInterface:
|
||||
try:
|
||||
# Note: Conditional for test compatibility.
|
||||
if not BlockchainInterfaceFactory.is_interface_initialized(eth_provider_uri=eth_provider_uri):
|
||||
BlockchainInterfaceFactory.initialize_interface(eth_provider_uri=eth_provider_uri,
|
||||
light=light,
|
||||
emitter=emitter)
|
||||
if not BlockchainInterfaceFactory.is_interface_initialized(
|
||||
endpoint=blockchain_endpoint
|
||||
):
|
||||
BlockchainInterfaceFactory.initialize_interface(
|
||||
endpoint=blockchain_endpoint, light=light, emitter=emitter
|
||||
)
|
||||
emitter.echo(message=CONNECTING_TO_BLOCKCHAIN)
|
||||
blockchain = BlockchainInterfaceFactory.get_interface(eth_provider_uri=eth_provider_uri)
|
||||
blockchain = BlockchainInterfaceFactory.get_interface(
|
||||
endpoint=blockchain_endpoint
|
||||
)
|
||||
return blockchain
|
||||
except Exception as e:
|
||||
if debug:
|
||||
|
|
|
@ -16,8 +16,8 @@ from constant_sorrow.constants import (
|
|||
)
|
||||
from eth_utils.address import is_checksum_address
|
||||
|
||||
from nucypher.blockchain.eth.domains import TACoDomain
|
||||
from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory
|
||||
from nucypher.blockchain.eth.networks import NetworksInventory
|
||||
from nucypher.blockchain.eth.registry import (
|
||||
ContractRegistry,
|
||||
LocalRegistrySource,
|
||||
|
@ -303,11 +303,11 @@ class CharacterConfiguration(BaseConfiguration):
|
|||
'Sideways Engagement' of Character classes; a reflection of input parameters.
|
||||
"""
|
||||
|
||||
VERSION = 7 # bump when static payload scheme changes
|
||||
VERSION = 8 # bump when static payload scheme changes
|
||||
|
||||
CHARACTER_CLASS = NotImplemented
|
||||
MNEMONIC_KEYSTORE = False
|
||||
DEFAULT_DOMAIN = NetworksInventory.DEFAULT
|
||||
DEFAULT_DOMAIN = TACoDomain.DEFAULT_DOMAIN_NAME
|
||||
DEFAULT_NETWORK_MIDDLEWARE = RestMiddleware
|
||||
TEMP_CONFIGURATION_DIR_PREFIX = 'tmp-nucypher'
|
||||
SIGNER_ENVVAR = None
|
||||
|
@ -321,7 +321,6 @@ class CharacterConfiguration(BaseConfiguration):
|
|||
|
||||
# Payments
|
||||
DEFAULT_PRE_PAYMENT_METHOD = "SubscriptionManager"
|
||||
DEFAULT_PRE_PAYMENT_NETWORK = "polygon"
|
||||
|
||||
# Fields specified here are *not* passed into the Character's constructor
|
||||
# and can be understood as configuration fields only.
|
||||
|
@ -334,8 +333,6 @@ class CharacterConfiguration(BaseConfiguration):
|
|||
"max_gas_price", # gwei
|
||||
"signer_uri",
|
||||
"keystore_path",
|
||||
"pre_payment_provider",
|
||||
"pre_payment_network",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
|
@ -368,20 +365,17 @@ class CharacterConfiguration(BaseConfiguration):
|
|||
# Blockchain
|
||||
poa: Optional[bool] = None,
|
||||
light: bool = False,
|
||||
eth_provider_uri: Optional[str] = None,
|
||||
eth_endpoint: Optional[str] = None,
|
||||
polygon_endpoint: Optional[str] = None,
|
||||
gas_strategy: Union[Callable, str] = DEFAULT_GAS_STRATEGY,
|
||||
max_gas_price: Optional[int] = None,
|
||||
signer_uri: Optional[str] = None,
|
||||
# Payments
|
||||
# TODO: Resolve code prefixing below, possibly with the use of nested configuration fields
|
||||
pre_payment_method: Optional[str] = None,
|
||||
pre_payment_provider: Optional[str] = None,
|
||||
pre_payment_network: Optional[str] = None,
|
||||
# Registries
|
||||
registry: Optional[ContractRegistry] = None,
|
||||
registry_filepath: Optional[Path] = None,
|
||||
policy_registry: Optional[ContractRegistry] = None,
|
||||
policy_registry_filepath: Optional[Path] = None,
|
||||
):
|
||||
|
||||
self.log = Logger(self.__class__.__name__)
|
||||
|
@ -412,17 +406,16 @@ class CharacterConfiguration(BaseConfiguration):
|
|||
self.registry = registry or NO_BLOCKCHAIN_CONNECTION.bool_value(False)
|
||||
self.registry_filepath = registry_filepath or UNINITIALIZED_CONFIGURATION
|
||||
|
||||
self.policy_registry = policy_registry or NO_BLOCKCHAIN_CONNECTION.bool_value(False)
|
||||
self.policy_registry_filepath = policy_registry_filepath or UNINITIALIZED_CONFIGURATION
|
||||
|
||||
# Blockchain
|
||||
self.poa = poa
|
||||
self.is_light = light
|
||||
self.eth_provider_uri = eth_provider_uri or NO_BLOCKCHAIN_CONNECTION
|
||||
self.eth_endpoint = eth_endpoint or NO_BLOCKCHAIN_CONNECTION
|
||||
self.polygon_endpoint = polygon_endpoint or NO_BLOCKCHAIN_CONNECTION
|
||||
self.signer_uri = signer_uri or None
|
||||
|
||||
# Learner
|
||||
self.domain = domain
|
||||
self.taco_domain_info = TACoDomain.get_domain_info(self.domain)
|
||||
self.learn_on_same_thread = learn_on_same_thread
|
||||
self.abort_on_learning_error = abort_on_learning_error
|
||||
self.start_learning_now = start_learning_now
|
||||
|
@ -442,32 +435,9 @@ class CharacterConfiguration(BaseConfiguration):
|
|||
|
||||
self.gas_strategy = gas_strategy
|
||||
self.max_gas_price = max_gas_price # gwei
|
||||
is_initialized = BlockchainInterfaceFactory.is_interface_initialized(
|
||||
eth_provider_uri=self.eth_provider_uri
|
||||
)
|
||||
if not is_initialized and eth_provider_uri:
|
||||
BlockchainInterfaceFactory.initialize_interface(
|
||||
eth_provider_uri=self.eth_provider_uri,
|
||||
poa=self.poa,
|
||||
light=self.is_light,
|
||||
emitter=emitter,
|
||||
gas_strategy=self.gas_strategy,
|
||||
max_gas_price=self.max_gas_price,
|
||||
)
|
||||
else:
|
||||
self.log.warn(
|
||||
f"Using existing blockchain interface connection ({self.eth_provider_uri})."
|
||||
)
|
||||
|
||||
# TODO: this is potential fix for multichain connection, if we want to use it build it out into a loop
|
||||
# for uri in eth_provider_uri (list of uris fom config):
|
||||
BlockchainInterfaceFactory.get_or_create_interface(
|
||||
eth_provider_uri=pre_payment_provider,
|
||||
poa=self.poa,
|
||||
light=self.is_light,
|
||||
emitter=emitter,
|
||||
gas_strategy=self.gas_strategy,
|
||||
max_gas_price=self.max_gas_price,
|
||||
self._connect_to_endpoints(
|
||||
emitter=emitter, endpoints=[self.eth_endpoint, self.polygon_endpoint]
|
||||
)
|
||||
|
||||
if not self.registry:
|
||||
|
@ -483,8 +453,9 @@ class CharacterConfiguration(BaseConfiguration):
|
|||
self.registry = ContractRegistry(source=source)
|
||||
self.log.info(f"Using local registry ({self.registry}).")
|
||||
|
||||
self.testnet = self.domain != NetworksInventory.MAINNET
|
||||
self.signer = Signer.from_signer_uri(self.signer_uri, testnet=self.testnet)
|
||||
self.signer = Signer.from_signer_uri(
|
||||
self.signer_uri, testnet=self.taco_domain_info.is_testnet
|
||||
)
|
||||
|
||||
#
|
||||
# Onchain Payments & Policies
|
||||
|
@ -494,32 +465,9 @@ class CharacterConfiguration(BaseConfiguration):
|
|||
from nucypher.config.characters import BobConfiguration
|
||||
|
||||
if not isinstance(self, BobConfiguration):
|
||||
# if not pre_payment_provider:
|
||||
# raise self.ConfigurationError("payment provider is required.")
|
||||
self.pre_payment_method = (
|
||||
pre_payment_method or self.DEFAULT_PRE_PAYMENT_METHOD
|
||||
)
|
||||
self.pre_payment_network = (
|
||||
pre_payment_network or self.DEFAULT_PRE_PAYMENT_NETWORK
|
||||
)
|
||||
self.pre_payment_provider = pre_payment_provider or (
|
||||
self.eth_provider_uri or None
|
||||
) # default to L1 payments
|
||||
|
||||
# TODO: Dedupe
|
||||
if not self.policy_registry:
|
||||
if not self.policy_registry_filepath:
|
||||
self.log.info("Fetching latest policy registry from source.")
|
||||
self.policy_registry = ContractRegistry.from_latest_publication(
|
||||
domain=self.pre_payment_network
|
||||
)
|
||||
else:
|
||||
self.policy_registry = ContractRegistry(
|
||||
filepath=self.policy_registry_filepath
|
||||
)
|
||||
self.log.info(
|
||||
f"Using local policy registry ({self.policy_registry})."
|
||||
)
|
||||
|
||||
if dev_mode:
|
||||
self.__temp_dir = UNINITIALIZED_CONFIGURATION
|
||||
|
@ -533,11 +481,32 @@ class CharacterConfiguration(BaseConfiguration):
|
|||
|
||||
# Network
|
||||
self.network_middleware = network_middleware or self.DEFAULT_NETWORK_MIDDLEWARE(
|
||||
registry=self.registry, eth_provider_uri=self.eth_provider_uri
|
||||
registry=self.registry, eth_endpoint=self.eth_endpoint
|
||||
)
|
||||
|
||||
super().__init__(filepath=self.config_file_location, config_root=self.config_root)
|
||||
|
||||
def _connect_to_endpoints(self, emitter, endpoints: List[str]) -> None:
|
||||
for endpoint in endpoints:
|
||||
if endpoint and endpoint != NO_BLOCKCHAIN_CONNECTION:
|
||||
is_initialized = BlockchainInterfaceFactory.is_interface_initialized(
|
||||
endpoint=endpoint
|
||||
)
|
||||
|
||||
if not is_initialized:
|
||||
BlockchainInterfaceFactory.initialize_interface(
|
||||
endpoint=endpoint,
|
||||
poa=self.poa,
|
||||
light=self.is_light,
|
||||
emitter=emitter,
|
||||
gas_strategy=self.gas_strategy,
|
||||
max_gas_price=self.max_gas_price,
|
||||
)
|
||||
else:
|
||||
self.log.warn(
|
||||
f"Using existing blockchain interface connection ({endpoint})."
|
||||
)
|
||||
|
||||
def __call__(self, **character_kwargs):
|
||||
return self.produce(**character_kwargs)
|
||||
|
||||
|
@ -703,12 +672,12 @@ class CharacterConfiguration(BaseConfiguration):
|
|||
)
|
||||
|
||||
# Optional values (mode)
|
||||
if self.eth_provider_uri:
|
||||
if self.eth_endpoint:
|
||||
if not self.signer_uri:
|
||||
self.signer_uri = self.eth_provider_uri
|
||||
self.signer_uri = self.eth_endpoint
|
||||
payload.update(
|
||||
dict(
|
||||
eth_provider_uri=self.eth_provider_uri,
|
||||
eth_endpoint=self.eth_endpoint,
|
||||
poa=self.poa,
|
||||
light=self.is_light,
|
||||
signer_uri=self.signer_uri,
|
||||
|
@ -717,6 +686,11 @@ class CharacterConfiguration(BaseConfiguration):
|
|||
if self.registry_filepath:
|
||||
payload.update(dict(registry_filepath=self.registry_filepath))
|
||||
|
||||
if self.polygon_endpoint:
|
||||
payload.update(
|
||||
polygon_endpoint=self.polygon_endpoint,
|
||||
)
|
||||
|
||||
# Gas Price
|
||||
__max_price = str(self.max_gas_price) if self.max_gas_price else None
|
||||
payload.update(dict(gas_strategy=self.gas_strategy, max_gas_price=__max_price))
|
||||
|
@ -840,8 +814,8 @@ class CharacterConfiguration(BaseConfiguration):
|
|||
#
|
||||
# Strategy-Based (current implementation, inflexible & hardcoded)
|
||||
# 'pre_payment_strategy': 'SubscriptionManager'
|
||||
# 'pre_payment_network': 'matic'
|
||||
# 'pre_payment_provider': 'https:///matic.infura.io....'
|
||||
# 'network': 'polygon'
|
||||
# 'blockchain_endpoint': 'https:///polygon.infura.io....'
|
||||
#
|
||||
# Contract-Targeted (alternative implementation, flexible & generic)
|
||||
# 'pre_payment': {
|
||||
|
@ -860,9 +834,9 @@ class CharacterConfiguration(BaseConfiguration):
|
|||
if pre_payment_class.ONCHAIN:
|
||||
# on-chain payment strategies require a blockchain connection
|
||||
pre_payment_strategy = pre_payment_class(
|
||||
network=self.pre_payment_network,
|
||||
eth_provider=self.pre_payment_provider,
|
||||
registry=self.policy_registry,
|
||||
domain=self.taco_domain_info.name,
|
||||
blockchain_endpoint=self.polygon_endpoint,
|
||||
registry=self.registry,
|
||||
)
|
||||
else:
|
||||
pre_payment_strategy = pre_payment_class()
|
||||
|
|
|
@ -5,7 +5,6 @@ from typing import Dict, List, Optional
|
|||
from cryptography.x509 import Certificate
|
||||
from eth_utils import is_checksum_address
|
||||
|
||||
from nucypher.blockchain.eth.networks import NetworksInventory
|
||||
from nucypher.config.base import CharacterConfiguration
|
||||
from nucypher.config.constants import (
|
||||
NUCYPHER_ENVVAR_ALICE_ETH_PASSWORD,
|
||||
|
@ -36,7 +35,7 @@ class UrsulaConfiguration(CharacterConfiguration):
|
|||
keystore_path: Optional[Path] = None,
|
||||
rest_port: Optional[int] = None,
|
||||
certificate: Optional[Certificate] = None,
|
||||
condition_provider_uris: Optional[Dict[str, List[str]]] = None,
|
||||
condition_blockchain_endpoints: Optional[Dict[str, List[str]]] = None,
|
||||
*args,
|
||||
**kwargs,
|
||||
) -> None:
|
||||
|
@ -61,35 +60,38 @@ class UrsulaConfiguration(CharacterConfiguration):
|
|||
|
||||
# json configurations don't allow for integer keyed dictionaries
|
||||
# so convert string chain id to integer
|
||||
self.condition_provider_uris = dict()
|
||||
if condition_provider_uris:
|
||||
for chain, providers in condition_provider_uris.items():
|
||||
self.condition_blockchain_endpoints = dict()
|
||||
if condition_blockchain_endpoints:
|
||||
for chain, blockchain_endpoint in condition_blockchain_endpoints.items():
|
||||
# convert chain from string key (for json) to integer
|
||||
self.condition_provider_uris[int(chain)] = providers
|
||||
self.configure_condition_provider_uris()
|
||||
|
||||
def configure_condition_provider_uris(self) -> None:
|
||||
"""Configure default condition provider URIs for mainnet and polygon network."""
|
||||
self.condition_blockchain_endpoints[int(chain)] = blockchain_endpoint
|
||||
self.configure_condition_blockchain_endpoints()
|
||||
|
||||
def configure_condition_blockchain_endpoints(self) -> None:
|
||||
"""Configure default condition provider URIs for eth and polygon network."""
|
||||
# Polygon
|
||||
polygon_chain_id = NetworksInventory.get_polygon_chain_id(
|
||||
self.pre_payment_network
|
||||
polygon_chain_id = self.taco_domain_info.polygon_chain.id
|
||||
polygon_endpoints = self.condition_blockchain_endpoints.get(
|
||||
polygon_chain_id, []
|
||||
)
|
||||
polygon_provider_uris = self.condition_provider_uris.get(polygon_chain_id, [])
|
||||
if not polygon_provider_uris:
|
||||
self.condition_provider_uris[polygon_chain_id] = polygon_provider_uris
|
||||
if not polygon_endpoints:
|
||||
self.condition_blockchain_endpoints[polygon_chain_id] = polygon_endpoints
|
||||
|
||||
if self.pre_payment_provider not in polygon_provider_uris:
|
||||
polygon_provider_uris.append(self.pre_payment_provider)
|
||||
if self.polygon_endpoint not in polygon_endpoints:
|
||||
polygon_endpoints.append(self.polygon_endpoint)
|
||||
|
||||
# Ethereum
|
||||
staking_chain_id = NetworksInventory.get_ethereum_chain_id(self.domain)
|
||||
staking_provider_uris = self.condition_provider_uris.get(staking_chain_id, [])
|
||||
if not staking_provider_uris:
|
||||
self.condition_provider_uris[staking_chain_id] = staking_provider_uris
|
||||
staking_chain_id = self.taco_domain_info.eth_chain.id
|
||||
staking_chain_endpoints = self.condition_blockchain_endpoints.get(
|
||||
staking_chain_id, []
|
||||
)
|
||||
if not staking_chain_endpoints:
|
||||
self.condition_blockchain_endpoints[
|
||||
staking_chain_id
|
||||
] = staking_chain_endpoints
|
||||
|
||||
if self.eth_provider_uri not in staking_provider_uris:
|
||||
staking_provider_uris.append(self.eth_provider_uri)
|
||||
if self.eth_endpoint not in staking_chain_endpoints:
|
||||
staking_chain_endpoints.append(self.eth_endpoint)
|
||||
|
||||
@classmethod
|
||||
def address_from_filepath(cls, filepath: Path) -> str:
|
||||
|
@ -114,13 +116,11 @@ class UrsulaConfiguration(CharacterConfiguration):
|
|||
operator_address=self.operator_address,
|
||||
rest_host=self.rest_host,
|
||||
rest_port=self.rest_port,
|
||||
condition_provider_uris=self.condition_provider_uris,
|
||||
condition_blockchain_endpoints=self.condition_blockchain_endpoints,
|
||||
|
||||
# PRE Payments
|
||||
# TODO: Resolve variable prefixing below (uses nested configuration fields?)
|
||||
pre_payment_method=self.pre_payment_method,
|
||||
pre_payment_provider=self.pre_payment_provider,
|
||||
pre_payment_network=self.pre_payment_network,
|
||||
)
|
||||
return {**super().static_payload(), **payload}
|
||||
|
||||
|
@ -181,8 +181,6 @@ class AliceConfiguration(CharacterConfiguration):
|
|||
payload = dict(
|
||||
threshold=self.threshold,
|
||||
shares=self.shares,
|
||||
pre_payment_network=self.pre_payment_network,
|
||||
pre_payment_provider=self.pre_payment_provider,
|
||||
pre_payment_method=self.pre_payment_method,
|
||||
rate=self.rate,
|
||||
duration=self.duration,
|
||||
|
|
|
@ -5,6 +5,7 @@ from .configuration_v3_to_v4 import configuration_v3_to_v4
|
|||
from .configuration_v4_to_v5 import configuration_v4_to_v5
|
||||
from .configuration_v5_to_v6 import configuration_v5_to_v6
|
||||
from .configuration_v6_to_v7 import configuration_v6_to_v7
|
||||
from .configuration_v7_to_v8 import configuration_v7_to_v8
|
||||
|
||||
MIGRATIONS = OrderedDict(
|
||||
{
|
||||
|
@ -14,5 +15,6 @@ MIGRATIONS = OrderedDict(
|
|||
(4, 5): configuration_v4_to_v5,
|
||||
(5, 6): configuration_v5_to_v6,
|
||||
(6, 7): configuration_v6_to_v7,
|
||||
(7, 8): configuration_v7_to_v8,
|
||||
}
|
||||
)
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
from typing import Dict
|
||||
|
||||
from nucypher.blockchain.eth.networks import NetworksInventory
|
||||
from nucypher.blockchain.eth.domains import TACoDomain
|
||||
from nucypher.config.migrations.common import perform_migration
|
||||
|
||||
|
||||
def __migration(config: Dict) -> Dict:
|
||||
taco_domain_info = TACoDomain.get_domain_info(config["domain"])
|
||||
eth_provider = config["eth_provider_uri"]
|
||||
eth_chain_id = NetworksInventory.get_ethereum_chain_id(config["domain"])
|
||||
eth_chain_id = taco_domain_info.eth_chain.id
|
||||
polygon_provider = config["payment_provider"]
|
||||
polygon_chain_id = NetworksInventory.get_polygon_chain_id(config["payment_network"])
|
||||
polygon_chain_id = taco_domain_info.polygon_chain.id
|
||||
if "condition_provider_uris" in config:
|
||||
return config
|
||||
config["condition_provider_uris"] = {
|
||||
|
|
|
@ -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
|
||||
)
|
|
@ -28,19 +28,17 @@ class NucypherMiddlewareClient:
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
eth_provider_uri: Optional[str],
|
||||
eth_endpoint: Optional[str],
|
||||
registry: Optional[ContractRegistry] = None,
|
||||
storage: Optional[NodeStorage] = None,
|
||||
*args,
|
||||
**kwargs,
|
||||
):
|
||||
if not eth_provider_uri:
|
||||
raise ValueError(
|
||||
"eth_provider_uri is required for NucypherMiddlewareClient"
|
||||
)
|
||||
if not eth_endpoint:
|
||||
raise ValueError("eth_endpoint is required for NucypherMiddlewareClient")
|
||||
|
||||
self.registry = registry
|
||||
self.eth_provider_uri = eth_provider_uri
|
||||
self.eth_endpoint = eth_endpoint
|
||||
self.storage = storage or ForgetfulNodeStorage() # for certificate storage
|
||||
|
||||
def get_certificate(self,
|
||||
|
@ -88,7 +86,11 @@ class NucypherMiddlewareClient:
|
|||
if node_or_sprout:
|
||||
if node_or_sprout is not EXEMPT_FROM_VERIFICATION:
|
||||
node = node_or_sprout.mature() # Morph into a node.
|
||||
node.verify_node(network_middleware_client=self, registry=self.registry, eth_provider_uri=self.eth_provider_uri)
|
||||
node.verify_node(
|
||||
network_middleware_client=self,
|
||||
registry=self.registry,
|
||||
eth_endpoint=self.eth_endpoint,
|
||||
)
|
||||
return self.parse_node_or_host_and_port(node_or_sprout, host, port)
|
||||
|
||||
def parse_node_or_host_and_port(self, node, host, port):
|
||||
|
@ -249,8 +251,8 @@ class RestMiddleware:
|
|||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(status=HTTPStatus.FORBIDDEN, *args, **kwargs)
|
||||
|
||||
def __init__(self, eth_provider_uri: str, registry=None):
|
||||
self.client = self._client_class(registry=registry, eth_provider_uri=eth_provider_uri)
|
||||
def __init__(self, eth_endpoint: str, registry=None):
|
||||
self.client = self._client_class(registry=registry, eth_endpoint=eth_endpoint)
|
||||
|
||||
def request_revocation(self, ursula, revocation):
|
||||
# TODO: Implement offchain revocation #2787
|
||||
|
|
|
@ -28,7 +28,7 @@ from nucypher.acumen.nicknames import Nickname
|
|||
from nucypher.acumen.perception import FleetSensor
|
||||
from nucypher.blockchain.eth.agents import ContractAgency, TACoApplicationAgent
|
||||
from nucypher.blockchain.eth.constants import NULL_ADDRESS
|
||||
from nucypher.blockchain.eth.networks import NetworksInventory
|
||||
from nucypher.blockchain.eth.domains import TACoDomain
|
||||
from nucypher.blockchain.eth.registry import ContractRegistry
|
||||
from nucypher.config.constants import SeednodeMetadata
|
||||
from nucypher.config.storages import ForgetfulNodeStorage
|
||||
|
@ -46,14 +46,13 @@ from nucypher.network.protocols import InterfaceInfo, SuspiciousActivity
|
|||
from nucypher.utilities.logging import Logger
|
||||
|
||||
TEACHER_NODES = {
|
||||
NetworksInventory.MAINNET: (
|
||||
TACoDomain.MAINNET.name: (
|
||||
'https://closest-seed.nucypher.network:9151',
|
||||
'https://seeds.nucypher.network',
|
||||
'https://mainnet.nucypher.network:9151',
|
||||
),
|
||||
NetworksInventory.LYNX: ("https://lynx.nucypher.network:9151",),
|
||||
NetworksInventory.TAPIR: ("https://tapir.nucypher.network:9151",),
|
||||
NetworksInventory.ORYX: ("https://oryx.nucypher.network:9151",),
|
||||
TACoDomain.LYNX.name: ("https://lynx.nucypher.network:9151",),
|
||||
TACoDomain.TAPIR.name: ("https://tapir.nucypher.network:9151",),
|
||||
}
|
||||
|
||||
|
||||
|
@ -271,8 +270,9 @@ class Learner:
|
|||
|
||||
self.learning_deferred = Deferred()
|
||||
self.domain = domain
|
||||
self.taco_domain_info = TACoDomain.get_domain_info(self.domain)
|
||||
default_middleware = self.__DEFAULT_MIDDLEWARE_CLASS(
|
||||
registry=self.registry, eth_provider_uri=self.eth_provider_uri
|
||||
registry=self.registry, eth_endpoint=self.eth_endpoint
|
||||
)
|
||||
self.network_middleware = network_middleware or default_middleware
|
||||
self.save_metadata = save_metadata
|
||||
|
@ -359,7 +359,7 @@ class Learner:
|
|||
maybe_sage_node = self.node_class.from_teacher_uri(
|
||||
teacher_uri=uri,
|
||||
min_stake=0,
|
||||
provider_uri=self.eth_provider_uri,
|
||||
eth_endpoint=self.eth_endpoint,
|
||||
network_middleware=self.network_middleware,
|
||||
registry=self.registry,
|
||||
)
|
||||
|
@ -383,7 +383,7 @@ class Learner:
|
|||
seed_node = self.node_class.from_seednode_metadata(
|
||||
seednode_metadata=seednode_metadata,
|
||||
network_middleware=self.network_middleware,
|
||||
provider_uri=self.eth_provider_uri,
|
||||
eth_endpoint=self.eth_endpoint,
|
||||
)
|
||||
except Exception as e:
|
||||
# TODO: log traceback here?
|
||||
|
@ -472,7 +472,7 @@ class Learner:
|
|||
force=force_verification_recheck,
|
||||
network_middleware_client=self.network_middleware.client,
|
||||
registry=registry,
|
||||
eth_provider_uri=self.eth_provider_uri,
|
||||
eth_endpoint=self.eth_endpoint,
|
||||
)
|
||||
except SSLError:
|
||||
# TODO: Bucket this node as having bad TLS info - maybe it's an update that hasn't fully propagated? 567
|
||||
|
@ -758,7 +758,7 @@ class Learner:
|
|||
try:
|
||||
node_on_the_other_end = self.node_class.from_seednode_metadata(
|
||||
stranger.seed_node_metadata(),
|
||||
provider_uri=self.provider_uri,
|
||||
eth_endpoint=self.eth_endpoint,
|
||||
network_middleware=self.network_middleware,
|
||||
)
|
||||
if node_on_the_other_end != stranger:
|
||||
|
@ -1040,7 +1040,7 @@ class Teacher:
|
|||
return bytes(response)
|
||||
|
||||
def _operator_is_bonded(
|
||||
self, provider_uri: str, registry: ContractRegistry
|
||||
self, eth_endpoint: str, registry: ContractRegistry
|
||||
) -> bool:
|
||||
"""
|
||||
This method assumes the stamp's signature is valid and accurate.
|
||||
|
@ -1048,7 +1048,7 @@ class Teacher:
|
|||
the case that the "staking provider" isn't "staking" (e.g., all her tokens have been slashed).
|
||||
"""
|
||||
application_agent = ContractAgency.get_agent(
|
||||
TACoApplicationAgent, provider_uri=provider_uri, registry=registry
|
||||
TACoApplicationAgent, blockchain_endpoint=eth_endpoint, registry=registry
|
||||
) # type: TACoApplicationAgent
|
||||
staking_provider_address = application_agent.get_staking_provider_from_operator(operator_address=self.operator_address)
|
||||
if staking_provider_address == NULL_ADDRESS:
|
||||
|
@ -1056,14 +1056,14 @@ class Teacher:
|
|||
return staking_provider_address == self.checksum_address
|
||||
|
||||
def _staking_provider_is_really_staking(
|
||||
self, registry: ContractRegistry, eth_provider_uri: Optional[str] = None
|
||||
self, registry: ContractRegistry, eth_endpoint: Optional[str] = None
|
||||
) -> bool:
|
||||
"""
|
||||
This method assumes the stamp's signature is valid and accurate.
|
||||
As a follow-up, this checks that the staking provider is, indeed, staking.
|
||||
"""
|
||||
application_agent = ContractAgency.get_agent(
|
||||
TACoApplicationAgent, registry=registry, provider_uri=eth_provider_uri
|
||||
TACoApplicationAgent, registry=registry, blockchain_endpoint=eth_endpoint
|
||||
) # type: TACoApplicationAgent
|
||||
is_staking = application_agent.is_authorized(staking_provider=self.checksum_address) # checksum address here is staking provider
|
||||
return is_staking
|
||||
|
@ -1071,7 +1071,7 @@ class Teacher:
|
|||
def validate_operator(
|
||||
self,
|
||||
registry: ContractRegistry = None,
|
||||
eth_provider_uri: Optional[str] = None,
|
||||
eth_endpoint: Optional[str] = None,
|
||||
) -> None:
|
||||
# TODO: restore this enforcement
|
||||
# if registry and not eth_provider_uri:
|
||||
|
@ -1088,14 +1088,14 @@ class Teacher:
|
|||
# On-chain staking check, if registry is present
|
||||
if registry:
|
||||
if not self._operator_is_bonded(
|
||||
registry=registry, provider_uri=eth_provider_uri
|
||||
registry=registry, eth_endpoint=eth_endpoint
|
||||
): # <-- Blockchain CALL
|
||||
message = f"Operator {self.operator_address} is not bonded to staking provider {self.checksum_address}"
|
||||
self.log.debug(message)
|
||||
raise self.UnbondedOperator(message)
|
||||
|
||||
if self._staking_provider_is_really_staking(
|
||||
registry=registry, eth_provider_uri=eth_provider_uri
|
||||
registry=registry, eth_endpoint=eth_endpoint
|
||||
): # <-- Blockchain CALL
|
||||
self.log.info(f"Verified operator {self}")
|
||||
self.verified_operator = True
|
||||
|
@ -1115,7 +1115,7 @@ class Teacher:
|
|||
raise self.InvalidNode("Metadata signature is invalid")
|
||||
|
||||
def validate_metadata(
|
||||
self, registry: ContractRegistry = None, eth_provider_uri: Optional[str] = None
|
||||
self, registry: ContractRegistry = None, eth_endpoint: Optional[str] = None
|
||||
):
|
||||
# Verify the metadata signature
|
||||
if not self.verified_metadata:
|
||||
|
@ -1126,13 +1126,13 @@ class Teacher:
|
|||
return
|
||||
|
||||
# Offline check of valid stamp signature by worker
|
||||
self.validate_operator(registry=registry, eth_provider_uri=eth_provider_uri)
|
||||
self.validate_operator(registry=registry, eth_endpoint=eth_endpoint)
|
||||
|
||||
def verify_node(
|
||||
self,
|
||||
network_middleware_client,
|
||||
registry: ContractRegistry = None,
|
||||
eth_provider_uri: Optional[str] = None,
|
||||
eth_endpoint: Optional[str] = None,
|
||||
certificate_filepath: Optional[Path] = None,
|
||||
force: bool = False,
|
||||
) -> bool:
|
||||
|
@ -1165,7 +1165,7 @@ class Teacher:
|
|||
)
|
||||
|
||||
# This is both the stamp's client signature and interface metadata check; May raise InvalidNode
|
||||
self.validate_metadata(registry=registry, eth_provider_uri=eth_provider_uri)
|
||||
self.validate_metadata(registry=registry, eth_endpoint=eth_endpoint)
|
||||
|
||||
# The node's metadata is valid; let's be sure the interface is in order.
|
||||
if not certificate_filepath:
|
||||
|
|
|
@ -6,6 +6,7 @@ from nucypher_core import ReencryptionRequest
|
|||
from web3.types import ChecksumAddress, Timestamp, TxReceipt, Wei
|
||||
|
||||
from nucypher.blockchain.eth.agents import ContractAgency, SubscriptionManagerAgent
|
||||
from nucypher.blockchain.eth.domains import TACoDomain
|
||||
from nucypher.blockchain.eth.registry import ContractRegistry
|
||||
from nucypher.policy import policies
|
||||
|
||||
|
@ -64,17 +65,17 @@ class ContractPayment(PaymentMethod, ABC):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
eth_provider: str,
|
||||
network: str,
|
||||
blockchain_endpoint: str,
|
||||
domain: str,
|
||||
registry: Optional[ContractRegistry] = None,
|
||||
*args,
|
||||
**kwargs,
|
||||
):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.provider = eth_provider
|
||||
self.network = network
|
||||
self.blockchain_endpoint = blockchain_endpoint
|
||||
self.taco_domain_info = TACoDomain.get_domain_info(domain)
|
||||
if not registry:
|
||||
registry = ContractRegistry.from_latest_publication(domain=network)
|
||||
registry = ContractRegistry.from_latest_publication(domain=domain)
|
||||
self.registry = registry
|
||||
self.__agent = None # delay blockchain/registry reads until later
|
||||
|
||||
|
@ -84,7 +85,9 @@ class ContractPayment(PaymentMethod, ABC):
|
|||
if self.__agent:
|
||||
return self.__agent # get cache
|
||||
agent = ContractAgency.get_agent(
|
||||
agent_class=self._AGENT, provider_uri=self.provider, registry=self.registry
|
||||
agent_class=self._AGENT,
|
||||
blockchain_endpoint=self.blockchain_endpoint,
|
||||
registry=self.registry,
|
||||
)
|
||||
self.__agent = agent
|
||||
return self.__agent # set cache
|
||||
|
|
|
@ -22,15 +22,17 @@ def encode_constructor_arguments(web3: Web3,
|
|||
return data
|
||||
|
||||
|
||||
def connect_web3_provider(eth_provider_uri: str) -> None:
|
||||
def connect_web3_provider(blockchain_endpoint: str) -> None:
|
||||
"""
|
||||
Convenience function for connecting to an ethereum provider now.
|
||||
Convenience function for connecting to a blockchain provider now.
|
||||
This may be used to optimize the startup time of some applications by
|
||||
establishing the connection eagerly.
|
||||
"""
|
||||
from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory
|
||||
|
||||
if not BlockchainInterfaceFactory.is_interface_initialized(eth_provider_uri=eth_provider_uri):
|
||||
BlockchainInterfaceFactory.initialize_interface(eth_provider_uri=eth_provider_uri)
|
||||
interface = BlockchainInterfaceFactory.get_interface(eth_provider_uri=eth_provider_uri)
|
||||
if not BlockchainInterfaceFactory.is_interface_initialized(
|
||||
endpoint=blockchain_endpoint
|
||||
):
|
||||
BlockchainInterfaceFactory.initialize_interface(endpoint=blockchain_endpoint)
|
||||
interface = BlockchainInterfaceFactory.get_interface(endpoint=blockchain_endpoint)
|
||||
interface.connect()
|
||||
|
|
|
@ -69,13 +69,13 @@ def _request(url: str, certificate=None) -> Union[str, None]:
|
|||
|
||||
def _request_from_node(
|
||||
teacher,
|
||||
provider_uri: str,
|
||||
eth_endpoint: str,
|
||||
client: Optional[NucypherMiddlewareClient] = None,
|
||||
timeout: int = 2,
|
||||
log: Logger = IP_DETECTION_LOGGER,
|
||||
) -> Union[str, None]:
|
||||
if not client:
|
||||
client = NucypherMiddlewareClient(eth_provider_uri=provider_uri)
|
||||
client = NucypherMiddlewareClient(eth_endpoint=eth_endpoint)
|
||||
try:
|
||||
response = client.get(
|
||||
node_or_sprout=teacher, path="ping", timeout=timeout
|
||||
|
@ -100,8 +100,8 @@ def _request_from_node(
|
|||
|
||||
|
||||
def get_external_ip_from_default_teacher(
|
||||
network: str,
|
||||
provider_uri: str,
|
||||
domain: str,
|
||||
eth_endpoint: str,
|
||||
registry: Optional[ContractRegistry] = None,
|
||||
log: Logger = IP_DETECTION_LOGGER,
|
||||
) -> Union[str, None]:
|
||||
|
@ -111,21 +111,21 @@ def get_external_ip_from_default_teacher(
|
|||
|
||||
base_error = 'Cannot determine IP using default teacher'
|
||||
|
||||
if network not in TEACHER_NODES:
|
||||
log.debug(f'{base_error}: Unknown network "{network}".')
|
||||
if domain not in TEACHER_NODES:
|
||||
log.debug(f'{base_error}: Unknown domain "{domain}".')
|
||||
return
|
||||
|
||||
node_storage = LocalFileBasedNodeStorage()
|
||||
Ursula.set_cert_storage_function(node_storage.store_node_certificate)
|
||||
|
||||
external_ip = None
|
||||
for teacher_uri in TEACHER_NODES[network]:
|
||||
for teacher_uri in TEACHER_NODES[domain]:
|
||||
try:
|
||||
teacher = Ursula.from_teacher_uri(
|
||||
teacher_uri=teacher_uri, provider_uri=provider_uri, min_stake=0
|
||||
teacher_uri=teacher_uri, eth_endpoint=eth_endpoint, min_stake=0
|
||||
) # TODO: Handle customized min stake here.
|
||||
# TODO: Pass registry here to verify stake (not essential here since it's a hardcoded node)
|
||||
external_ip = _request_from_node(teacher=teacher, provider_uri=provider_uri)
|
||||
external_ip = _request_from_node(teacher=teacher, eth_endpoint=eth_endpoint)
|
||||
# Found a reachable teacher, return from loop
|
||||
if external_ip:
|
||||
break
|
||||
|
@ -134,7 +134,7 @@ def get_external_ip_from_default_teacher(
|
|||
continue
|
||||
|
||||
if not external_ip:
|
||||
log.debug(f'{base_error}: No teacher available for network "{network}".')
|
||||
log.debug(f'{base_error}: No teacher available for domain "{domain}".')
|
||||
return
|
||||
|
||||
return external_ip
|
||||
|
@ -142,7 +142,7 @@ def get_external_ip_from_default_teacher(
|
|||
|
||||
def get_external_ip_from_known_nodes(
|
||||
known_nodes: FleetSensor,
|
||||
provider_uri: str,
|
||||
eth_endpoint: str,
|
||||
sample_size: int = 3,
|
||||
log: Logger = IP_DETECTION_LOGGER,
|
||||
) -> Union[str, None]:
|
||||
|
@ -154,9 +154,9 @@ def get_external_ip_from_known_nodes(
|
|||
if len(known_nodes) < sample_size:
|
||||
return # There are too few known nodes
|
||||
sample = random.sample(list(known_nodes), sample_size)
|
||||
client = NucypherMiddlewareClient(eth_provider_uri=provider_uri)
|
||||
client = NucypherMiddlewareClient(eth_endpoint=eth_endpoint)
|
||||
for node in sample:
|
||||
ip = _request_from_node(teacher=node, client=client, provider_uri=provider_uri)
|
||||
ip = _request_from_node(teacher=node, client=client, eth_endpoint=eth_endpoint)
|
||||
if ip:
|
||||
log.info(f'Fetched external IP address ({ip}) from randomly selected known nodes.')
|
||||
return ip
|
||||
|
@ -171,7 +171,7 @@ def get_external_ip_from_centralized_source(log: Logger = IP_DETECTION_LOGGER) -
|
|||
|
||||
|
||||
def determine_external_ip_address(
|
||||
network: str, provider_uri: str, known_nodes: FleetSensor = None
|
||||
domain: str, eth_endpoint: str, known_nodes: FleetSensor = None
|
||||
) -> str:
|
||||
"""
|
||||
Attempts to automatically determine the external IP in the following priority:
|
||||
|
@ -186,13 +186,13 @@ def determine_external_ip_address(
|
|||
# primary source
|
||||
if known_nodes:
|
||||
rest_host = get_external_ip_from_known_nodes(
|
||||
known_nodes=known_nodes, provider_uri=provider_uri
|
||||
known_nodes=known_nodes, eth_endpoint=eth_endpoint
|
||||
)
|
||||
|
||||
# fallback 1
|
||||
if not rest_host:
|
||||
rest_host = get_external_ip_from_default_teacher(
|
||||
network=network, provider_uri=provider_uri
|
||||
domain=domain, eth_endpoint=eth_endpoint
|
||||
)
|
||||
|
||||
# fallback 2
|
||||
|
|
|
@ -121,9 +121,10 @@ class UrsulaInfoMetricsCollector(BaseMetricsCollector):
|
|||
|
||||
class BlockchainMetricsCollector(BaseMetricsCollector):
|
||||
"""Collector for Blockchain specific metrics."""
|
||||
def __init__(self, eth_provider_uri: str):
|
||||
|
||||
def __init__(self, eth_endpoint: str):
|
||||
super().__init__()
|
||||
self.eth_provider_uri = eth_provider_uri
|
||||
self.eth_endpoint = eth_endpoint
|
||||
|
||||
def initialize(self, metrics_prefix: str, registry: CollectorRegistry) -> None:
|
||||
self.metrics = {
|
||||
|
@ -138,7 +139,9 @@ class BlockchainMetricsCollector(BaseMetricsCollector):
|
|||
}
|
||||
|
||||
def _collect_internal(self) -> None:
|
||||
blockchain = BlockchainInterfaceFactory.get_or_create_interface(eth_provider_uri=self.eth_provider_uri)
|
||||
blockchain = BlockchainInterfaceFactory.get_or_create_interface(
|
||||
endpoint=self.eth_endpoint
|
||||
)
|
||||
self.metrics["eth_chain_id"].set(blockchain.client.chain_id)
|
||||
self.metrics["eth_current_block_number"].set(blockchain.client.block_number)
|
||||
|
||||
|
@ -150,12 +153,12 @@ class StakingProviderMetricsCollector(BaseMetricsCollector):
|
|||
self,
|
||||
staking_provider_address: ChecksumAddress,
|
||||
contract_registry: ContractRegistry,
|
||||
eth_provider_uri: str,
|
||||
eth_endpoint: str,
|
||||
):
|
||||
super().__init__()
|
||||
self.staking_provider_address = staking_provider_address
|
||||
self.contract_registry = contract_registry
|
||||
self.eth_provider_uri = eth_provider_uri
|
||||
self.eth_endpoint = eth_endpoint
|
||||
|
||||
def initialize(self, metrics_prefix: str, registry: CollectorRegistry) -> None:
|
||||
self.metrics = {
|
||||
|
@ -180,7 +183,7 @@ class StakingProviderMetricsCollector(BaseMetricsCollector):
|
|||
application_agent = ContractAgency.get_agent(
|
||||
TACoApplicationAgent,
|
||||
registry=self.contract_registry,
|
||||
provider_uri=self.eth_provider_uri,
|
||||
blockchain_endpoint=self.eth_endpoint,
|
||||
)
|
||||
authorized = application_agent.get_authorized_stake(
|
||||
staking_provider=self.staking_provider_address
|
||||
|
|
|
@ -157,16 +157,14 @@ def create_metrics_collectors(ursula: "lawful.Ursula") -> List[MetricsCollector]
|
|||
|
||||
# Blockchain prometheus
|
||||
# TODO possible include information about payment
|
||||
collectors.append(
|
||||
BlockchainMetricsCollector(eth_provider_uri=ursula.eth_provider_uri)
|
||||
)
|
||||
collectors.append(BlockchainMetricsCollector(eth_endpoint=ursula.eth_endpoint))
|
||||
|
||||
# Staking Provider prometheus
|
||||
collectors.append(
|
||||
StakingProviderMetricsCollector(
|
||||
staking_provider_address=ursula.checksum_address,
|
||||
contract_registry=ursula.registry,
|
||||
eth_provider_uri=ursula.eth_provider_uri,
|
||||
eth_endpoint=ursula.eth_endpoint,
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ from nucypher.blockchain.eth.agents import (
|
|||
TACoApplicationAgent,
|
||||
TACoChildApplicationAgent,
|
||||
)
|
||||
from nucypher.blockchain.eth.networks import NetworksInventory
|
||||
from nucypher.blockchain.eth.domains import TACoDomain
|
||||
from nucypher.blockchain.eth.registry import ContractRegistry
|
||||
from nucypher.utilities.emitters import StdoutEmitter
|
||||
from nucypher.utilities.logging import GlobalLoggerSettings
|
||||
|
@ -42,71 +42,56 @@ emitter = StdoutEmitter(verbosity=2)
|
|||
|
||||
@click.command()
|
||||
@click.option(
|
||||
"--eth-provider",
|
||||
"eth_provider_uri",
|
||||
"--domain",
|
||||
"domain",
|
||||
help="TACo domain",
|
||||
type=click.Choice(TACoDomain.SUPPORTED_DOMAIN_NAMES),
|
||||
default=TACoDomain.LYNX.name,
|
||||
)
|
||||
@click.option(
|
||||
"--eth-endpoint",
|
||||
"eth_endpoint",
|
||||
help="ETH staking network provider URI",
|
||||
type=click.STRING,
|
||||
required=True,
|
||||
)
|
||||
@click.option(
|
||||
"--eth-staking-network",
|
||||
"eth_staking_network",
|
||||
help="ETH staking network",
|
||||
type=click.Choice(NetworksInventory.ETH_NETWORKS),
|
||||
default="lynx",
|
||||
)
|
||||
@click.option(
|
||||
"--coordinator-provider",
|
||||
"coordinator_provider_uri",
|
||||
help="Coordinator network provider URI",
|
||||
"--polygon-endpoint",
|
||||
"polygon_endpoint",
|
||||
help="Polygon network provider URI",
|
||||
type=click.STRING,
|
||||
required=True,
|
||||
)
|
||||
@click.option(
|
||||
"--coordinator-network",
|
||||
"coordinator_network",
|
||||
help="Coordinator network",
|
||||
type=click.Choice(NetworksInventory.POLY_NETWORKS),
|
||||
default="mumbai",
|
||||
)
|
||||
def nucypher_agents(
|
||||
eth_provider_uri,
|
||||
eth_staking_network,
|
||||
coordinator_provider_uri,
|
||||
coordinator_network,
|
||||
domain,
|
||||
eth_endpoint,
|
||||
polygon_endpoint,
|
||||
):
|
||||
staking_registry = ContractRegistry.from_latest_publication(
|
||||
domain=eth_staking_network
|
||||
)
|
||||
emitter.echo(f"NOTICE: Connecting to {eth_staking_network} network", color="yellow")
|
||||
registry = ContractRegistry.from_latest_publication(domain=domain)
|
||||
emitter.echo(f"NOTICE: Connecting to {domain} domain", color="yellow")
|
||||
|
||||
taco_application_agent = ContractAgency.get_agent(
|
||||
agent_class=TACoApplicationAgent,
|
||||
registry=staking_registry,
|
||||
provider_uri=eth_provider_uri,
|
||||
registry=registry,
|
||||
blockchain_endpoint=eth_endpoint,
|
||||
) # type: TACoApplicationAgent
|
||||
|
||||
coordinator_network_registry = ContractRegistry.from_latest_publication(
|
||||
domain=coordinator_network
|
||||
)
|
||||
emitter.echo(f"NOTICE: Connecting to {coordinator_network} network", color="yellow")
|
||||
|
||||
taco_child_application_agent = ContractAgency.get_agent(
|
||||
agent_class=TACoChildApplicationAgent,
|
||||
registry=coordinator_network_registry,
|
||||
provider_uri=coordinator_provider_uri,
|
||||
registry=registry,
|
||||
blockchain_endpoint=polygon_endpoint,
|
||||
) # type: TACoChildApplicationAgent
|
||||
|
||||
coordinator_agent = ContractAgency.get_agent(
|
||||
agent_class=CoordinatorAgent,
|
||||
registry=coordinator_network_registry,
|
||||
provider_uri=coordinator_provider_uri,
|
||||
registry=registry,
|
||||
blockchain_endpoint=polygon_endpoint,
|
||||
) # type: CoordinatorAgent
|
||||
|
||||
subscription_manager_agent = ContractAgency.get_agent(
|
||||
agent_class=SubscriptionManagerAgent,
|
||||
registry=coordinator_network_registry,
|
||||
provider_uri=coordinator_provider_uri,
|
||||
registry=registry,
|
||||
blockchain_endpoint=polygon_endpoint,
|
||||
) # type: SubscriptionManagerAgent
|
||||
|
||||
message = (
|
||||
|
|
|
@ -11,6 +11,7 @@ from nucypher.blockchain.eth.agents import (
|
|||
CoordinatorAgent,
|
||||
TACoApplicationAgent,
|
||||
)
|
||||
from nucypher.blockchain.eth.domains import TACoDomain
|
||||
from nucypher.blockchain.eth.registry import ContractRegistry
|
||||
from nucypher.blockchain.eth.signers import InMemorySigner, Signer
|
||||
from nucypher.characters.lawful import Bob, Enrico
|
||||
|
@ -43,33 +44,26 @@ def get_transacting_power(signer: Signer):
|
|||
|
||||
@click.command()
|
||||
@click.option(
|
||||
"--eth-provider",
|
||||
"eth_provider_uri",
|
||||
"--domain",
|
||||
"domain",
|
||||
help="TACo Domain",
|
||||
type=click.Choice([TACoDomain.TAPIR.name, TACoDomain.LYNX.name]),
|
||||
default=TACoDomain.LYNX.name,
|
||||
)
|
||||
@click.option(
|
||||
"--eth-endpoint",
|
||||
"eth_endpoint",
|
||||
help="ETH staking network provider URI",
|
||||
type=click.STRING,
|
||||
required=True,
|
||||
)
|
||||
@click.option(
|
||||
"--eth-staking-network",
|
||||
"eth_staking_network",
|
||||
help="ETH staking network",
|
||||
type=click.Choice(["tapir", "lynx"]),
|
||||
default="lynx",
|
||||
)
|
||||
@click.option(
|
||||
"--coordinator-provider",
|
||||
"coordinator_provider_uri",
|
||||
help="Coordinator network provider URI",
|
||||
"--polygon-endpoint",
|
||||
"polygon_endpoint",
|
||||
help="Polygon network provider URI",
|
||||
type=click.STRING,
|
||||
required=True,
|
||||
)
|
||||
@click.option(
|
||||
"--coordinator-network",
|
||||
"coordinator_network",
|
||||
help="Coordinator network",
|
||||
type=click.Choice(["mumbai"]),
|
||||
default="mumbai",
|
||||
)
|
||||
@click.option(
|
||||
"--ritual-id",
|
||||
"ritual_id",
|
||||
|
@ -117,10 +111,9 @@ def get_transacting_power(signer: Signer):
|
|||
default=False,
|
||||
)
|
||||
def nucypher_dkg(
|
||||
eth_provider_uri,
|
||||
eth_staking_network,
|
||||
coordinator_provider_uri,
|
||||
coordinator_network,
|
||||
domain,
|
||||
eth_endpoint,
|
||||
polygon_endpoint,
|
||||
ritual_id,
|
||||
signer_uri,
|
||||
dkg_size,
|
||||
|
@ -161,22 +154,18 @@ def nucypher_dkg(
|
|||
),
|
||||
)
|
||||
|
||||
coordinator_network_registry = ContractRegistry.from_latest_publication(
|
||||
domain=coordinator_network
|
||||
)
|
||||
taco_domain_info = TACoDomain.get_domain_info(domain)
|
||||
registry = ContractRegistry.from_latest_publication(domain=domain)
|
||||
coordinator_agent = ContractAgency.get_agent(
|
||||
agent_class=CoordinatorAgent,
|
||||
registry=coordinator_network_registry,
|
||||
provider_uri=coordinator_provider_uri,
|
||||
registry=registry,
|
||||
blockchain_endpoint=polygon_endpoint,
|
||||
) # type: CoordinatorAgent
|
||||
|
||||
staking_network_registry = ContractRegistry.from_latest_publication(
|
||||
domain=eth_staking_network
|
||||
)
|
||||
application_agent = ContractAgency.get_agent(
|
||||
agent_class=TACoApplicationAgent,
|
||||
registry=staking_network_registry,
|
||||
provider_uri=eth_provider_uri,
|
||||
registry=registry,
|
||||
blockchain_endpoint=eth_endpoint,
|
||||
) # type: TACoApplicationAgent
|
||||
|
||||
#
|
||||
|
@ -188,7 +177,7 @@ def nucypher_dkg(
|
|||
# Get GlobalAllowList contract
|
||||
blockchain = coordinator_agent.blockchain
|
||||
allow_list = blockchain.get_contract_by_name(
|
||||
registry=coordinator_network_registry, contract_name=GLOBAL_ALLOW_LIST
|
||||
registry=registry, contract_name=GLOBAL_ALLOW_LIST
|
||||
)
|
||||
|
||||
#
|
||||
|
@ -202,7 +191,7 @@ def nucypher_dkg(
|
|||
|
||||
emitter.echo("--------- Initiating Ritual ---------", color="yellow")
|
||||
emitter.echo(
|
||||
f"Commencing DKG Ritual(s) on {coordinator_network} using {account_address}",
|
||||
f"Commencing DKG Ritual(s) on {taco_domain_info.polygon_chain.name} using {account_address}",
|
||||
color="green",
|
||||
)
|
||||
|
||||
|
@ -389,11 +378,10 @@ def nucypher_dkg(
|
|||
#
|
||||
emitter.echo("--------- Threshold Decryption ---------")
|
||||
bob = Bob(
|
||||
eth_provider_uri=eth_provider_uri,
|
||||
domain=eth_staking_network,
|
||||
registry=staking_network_registry,
|
||||
coordinator_network=coordinator_network,
|
||||
coordinator_provider_uri=coordinator_provider_uri,
|
||||
domain=domain,
|
||||
eth_endpoint=eth_endpoint,
|
||||
polygon_endpoint=polygon_endpoint,
|
||||
registry=registry,
|
||||
)
|
||||
bob.start_learning_loop(now=True)
|
||||
|
||||
|
|
|
@ -7,12 +7,12 @@ def test_get_agent_with_different_registries(test_registry):
|
|||
application_agent_1 = ContractAgency.get_agent(
|
||||
TACoApplicationAgent,
|
||||
registry=test_registry,
|
||||
provider_uri=TEST_ETH_PROVIDER_URI,
|
||||
blockchain_endpoint=TEST_ETH_PROVIDER_URI,
|
||||
)
|
||||
application_agent_2 = ContractAgency.get_agent(
|
||||
TACoApplicationAgent,
|
||||
registry=test_registry,
|
||||
provider_uri=TEST_ETH_PROVIDER_URI,
|
||||
blockchain_endpoint=TEST_ETH_PROVIDER_URI,
|
||||
)
|
||||
assert application_agent_2.registry == application_agent_1.registry == test_registry
|
||||
assert application_agent_2 is application_agent_1
|
||||
|
|
|
@ -13,7 +13,9 @@ from tests.constants import TEST_ETH_PROVIDER_URI
|
|||
@pytest.fixture(scope='module')
|
||||
def agent(testerchain, test_registry) -> NucypherTokenAgent:
|
||||
token_agent = ContractAgency.get_agent(
|
||||
NucypherTokenAgent, registry=test_registry, provider_uri=TEST_ETH_PROVIDER_URI
|
||||
NucypherTokenAgent,
|
||||
registry=test_registry,
|
||||
blockchain_endpoint=TEST_ETH_PROVIDER_URI,
|
||||
)
|
||||
return token_agent
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ def check(policy, bob, ursulas):
|
|||
|
||||
def test_grant_subscription_manager(alice, bob, ursulas):
|
||||
pre_payment_method = SubscriptionManagerPayment(
|
||||
eth_provider=TEST_ETH_PROVIDER_URI, network=TEMPORARY_DOMAIN
|
||||
blockchain_endpoint=TEST_ETH_PROVIDER_URI, domain=TEMPORARY_DOMAIN
|
||||
)
|
||||
alice.pre_payment_method = pre_payment_method
|
||||
policy = alice.grant(
|
||||
|
|
|
@ -137,12 +137,12 @@ def test_invalid_operators_tolerance(
|
|||
force=True,
|
||||
registry=test_registry,
|
||||
network_middleware_client=ursula.network_middleware.client,
|
||||
eth_provider_uri=ursula.eth_provider_uri,
|
||||
eth_endpoint=ursula.eth_endpoint,
|
||||
)
|
||||
# In particular, we know that it's bonded to a staker who is really staking.
|
||||
assert ursula.is_confirmed
|
||||
assert ursula._staking_provider_is_really_staking(
|
||||
registry=test_registry, eth_provider_uri=TEST_ETH_PROVIDER_URI
|
||||
registry=test_registry, eth_endpoint=TEST_ETH_PROVIDER_URI
|
||||
)
|
||||
|
||||
# OK. Now we learn about this new worker.
|
||||
|
@ -161,7 +161,7 @@ def test_invalid_operators_tolerance(
|
|||
|
||||
# OK...so...the staker is not staking anymore ...
|
||||
assert not ursula._staking_provider_is_really_staking(
|
||||
registry=test_registry, eth_provider_uri=TEST_ETH_PROVIDER_URI
|
||||
registry=test_registry, eth_endpoint=TEST_ETH_PROVIDER_URI
|
||||
)
|
||||
|
||||
# ... but the worker node still is "verified" (since we're not forcing on-chain verification)
|
||||
|
@ -176,7 +176,7 @@ def test_invalid_operators_tolerance(
|
|||
force=True,
|
||||
registry=test_registry,
|
||||
network_middleware_client=ursula.network_middleware.client,
|
||||
eth_provider_uri=TEST_ETH_PROVIDER_URI,
|
||||
eth_endpoint=TEST_ETH_PROVIDER_URI,
|
||||
)
|
||||
|
||||
#
|
||||
|
|
|
@ -16,7 +16,7 @@ def test_stakers_bond_to_ursulas(ursulas, test_registry, staking_providers):
|
|||
assert len(ursulas) == len(staking_providers)
|
||||
for ursula in ursulas:
|
||||
ursula.validate_operator(
|
||||
registry=test_registry, eth_provider_uri=TEST_ETH_PROVIDER_URI
|
||||
registry=test_registry, eth_endpoint=TEST_ETH_PROVIDER_URI
|
||||
)
|
||||
assert ursula.verified_operator
|
||||
|
||||
|
@ -106,7 +106,7 @@ def test_vladimir_uses_his_own_signing_key(alice, ursulas, test_registry):
|
|||
message = f"Operator {vladimir.operator_address} is not bonded"
|
||||
with pytest.raises(vladimir.UnbondedOperator, match=message):
|
||||
vladimir.validate_metadata(
|
||||
registry=test_registry, eth_provider_uri=TEST_ETH_PROVIDER_URI
|
||||
registry=test_registry, eth_endpoint=TEST_ETH_PROVIDER_URI
|
||||
)
|
||||
|
||||
|
||||
|
@ -159,9 +159,7 @@ def test_ursulas_reencrypt(ursulas, alice, bob, policy_value):
|
|||
assert plaintexts == [message]
|
||||
|
||||
# Let's consider also that a node may be down when granting
|
||||
alice.network_middleware = NodeIsDownMiddleware(
|
||||
eth_provider_uri=MOCK_ETH_PROVIDER_URI
|
||||
)
|
||||
alice.network_middleware = NodeIsDownMiddleware(eth_endpoint=MOCK_ETH_PROVIDER_URI)
|
||||
alice.network_middleware.node_is_down(ursulas[0])
|
||||
|
||||
with pytest.raises(Policy.NotEnoughUrsulas):
|
||||
|
|
|
@ -21,7 +21,7 @@ def test_character_transacting_power_signing(testerchain, test_registry):
|
|||
signer = Character(
|
||||
is_me=True,
|
||||
domain=TEMPORARY_DOMAIN,
|
||||
eth_provider_uri=TEST_ETH_PROVIDER_URI,
|
||||
eth_endpoint=TEST_ETH_PROVIDER_URI,
|
||||
registry=test_registry,
|
||||
checksum_address=eth_address,
|
||||
)
|
||||
|
|
|
@ -73,7 +73,7 @@ def mock_funded_account_password_keystore(
|
|||
taco_application_agent = ContractAgency.get_agent(
|
||||
TACoApplicationAgent,
|
||||
registry=test_registry,
|
||||
provider_uri=TEST_ETH_PROVIDER_URI,
|
||||
blockchain_endpoint=TEST_ETH_PROVIDER_URI,
|
||||
)
|
||||
taco_application_agent.bond_operator(
|
||||
staking_provider=provider_address,
|
||||
|
@ -123,17 +123,15 @@ def test_ursula_and_local_keystore_signer_integration(
|
|||
init_args = (
|
||||
"ursula",
|
||||
"init",
|
||||
"--network",
|
||||
TEMPORARY_DOMAIN,
|
||||
"--pre-payment-network",
|
||||
"--domain",
|
||||
TEMPORARY_DOMAIN,
|
||||
"--operator-address",
|
||||
worker_account.address,
|
||||
"--config-root",
|
||||
str(config_root_path.absolute()),
|
||||
"--eth-provider",
|
||||
"--eth-endpoint",
|
||||
TEST_ETH_PROVIDER_URI,
|
||||
"--pre-payment-provider",
|
||||
"--polygon-endpoint",
|
||||
TEST_POLYGON_PROVIDER_URI,
|
||||
"--rest-host",
|
||||
MOCK_IP_ADDRESS,
|
||||
|
|
|
@ -27,7 +27,7 @@ from tests.utils.ursula import select_test_port, start_pytest_ursula_services
|
|||
|
||||
@mock.patch('glob.glob', return_value=list())
|
||||
def test_missing_configuration_file(_default_filepath_mock, click_runner):
|
||||
cmd_args = ('ursula', 'run', '--network', TEMPORARY_DOMAIN)
|
||||
cmd_args = ("ursula", "run", "--domain", TEMPORARY_DOMAIN)
|
||||
result = click_runner.invoke(nucypher_cli, cmd_args, catch_exceptions=False)
|
||||
assert result.exit_code != 0
|
||||
configuration_type = UrsulaConfiguration.NAME
|
||||
|
@ -45,9 +45,9 @@ def test_ursula_run_with_prometheus_but_no_metrics_port(click_runner):
|
|||
"--dry-run", # Disable twisted reactor in subprocess
|
||||
"--lonely", # Do not load seednodes
|
||||
"--prometheus", # Specify collection of prometheus metrics
|
||||
"--eth-provider",
|
||||
"--eth-endpoint",
|
||||
TEST_ETH_PROVIDER_URI,
|
||||
"--pre-payment-provider",
|
||||
"--polygon-endpoint",
|
||||
TEST_POLYGON_PROVIDER_URI,
|
||||
)
|
||||
|
||||
|
@ -74,12 +74,10 @@ def test_run_lone_default_development_ursula(click_runner, ursulas, testerchain)
|
|||
"--lonely", # Do not load seednodes,
|
||||
"--operator-address",
|
||||
ursulas[0].operator_address,
|
||||
"--eth-provider",
|
||||
"--eth-endpoint",
|
||||
TEST_ETH_PROVIDER_URI,
|
||||
"--pre-payment-provider",
|
||||
"--polygon-endpoint",
|
||||
TEST_ETH_PROVIDER_URI,
|
||||
"--pre-payment-network",
|
||||
TEMPORARY_DOMAIN,
|
||||
)
|
||||
|
||||
result = yield threads.deferToThread(
|
||||
|
@ -128,12 +126,10 @@ def test_ursula_learns_via_cli(click_runner, ursulas, testerchain):
|
|||
"--dry-run", # Disable twisted reactor
|
||||
"--operator-address",
|
||||
ursulas[0].operator_address,
|
||||
"--eth-provider",
|
||||
"--eth-endpoint",
|
||||
TEST_ETH_PROVIDER_URI,
|
||||
"--pre-payment-provider",
|
||||
"--polygon-endpoint",
|
||||
TEST_ETH_PROVIDER_URI,
|
||||
"--pre-payment-network",
|
||||
TEMPORARY_DOMAIN,
|
||||
)
|
||||
|
||||
return threads.deferToThread(
|
||||
|
@ -180,15 +176,13 @@ def test_persistent_node_storage_integration(
|
|||
init_args = (
|
||||
"ursula",
|
||||
"init",
|
||||
"--eth-provider",
|
||||
"--eth-endpoint",
|
||||
TEST_ETH_PROVIDER_URI,
|
||||
"--pre-payment-provider",
|
||||
"--polygon-endpoint",
|
||||
TEST_POLYGON_PROVIDER_URI,
|
||||
"--operator-address",
|
||||
another_ursula,
|
||||
"--network",
|
||||
TEMPORARY_DOMAIN,
|
||||
"--pre-payment-network",
|
||||
"--domain",
|
||||
TEMPORARY_DOMAIN,
|
||||
"--rest-host",
|
||||
MOCK_IP_ADDRESS,
|
||||
|
|
|
@ -52,7 +52,7 @@ def erc20_evm_condition_balanceof(testerchain, test_registry):
|
|||
token = ContractAgency.get_agent(
|
||||
NucypherTokenAgent,
|
||||
registry=test_registry,
|
||||
provider_uri=TEST_ETH_PROVIDER_URI,
|
||||
blockchain_endpoint=TEST_ETH_PROVIDER_URI,
|
||||
)
|
||||
condition = ContractCondition(
|
||||
contract_address=token.contract.address,
|
||||
|
@ -115,7 +115,7 @@ def subscription_manager_get_policy_zeroized_policy_struct_condition(
|
|||
subscription_manager = ContractAgency.get_agent(
|
||||
SubscriptionManagerAgent,
|
||||
registry=test_registry,
|
||||
provider_uri=TEST_ETH_PROVIDER_URI,
|
||||
blockchain_endpoint=TEST_ETH_PROVIDER_URI,
|
||||
)
|
||||
condition = ContractCondition(
|
||||
contract_address=subscription_manager.contract.address,
|
||||
|
@ -135,7 +135,7 @@ def subscription_manager_is_active_policy_condition(testerchain, test_registry):
|
|||
subscription_manager = ContractAgency.get_agent(
|
||||
SubscriptionManagerAgent,
|
||||
registry=test_registry,
|
||||
provider_uri=TEST_ETH_PROVIDER_URI,
|
||||
blockchain_endpoint=TEST_ETH_PROVIDER_URI,
|
||||
)
|
||||
condition = ContractCondition(
|
||||
contract_address=subscription_manager.contract.address,
|
||||
|
@ -157,7 +157,7 @@ def custom_context_variable_erc20_condition(
|
|||
token = ContractAgency.get_agent(
|
||||
NucypherTokenAgent,
|
||||
registry=test_registry,
|
||||
provider_uri=TEST_ETH_PROVIDER_URI,
|
||||
blockchain_endpoint=TEST_ETH_PROVIDER_URI,
|
||||
)
|
||||
condition = ContractCondition(
|
||||
contract_address=token.contract.address,
|
||||
|
|
|
@ -346,7 +346,7 @@ def test_subscription_manager_get_policy_policy_struct_condition_key_tuple_evalu
|
|||
subscription_manager = ContractAgency.get_agent(
|
||||
SubscriptionManagerAgent,
|
||||
registry=test_registry,
|
||||
provider_uri=TEST_ETH_PROVIDER_URI,
|
||||
blockchain_endpoint=TEST_ETH_PROVIDER_URI,
|
||||
)
|
||||
|
||||
# test "sponsor" key (owner is the same as sponsor for this policy)
|
||||
|
@ -464,7 +464,7 @@ def test_subscription_manager_get_policy_policy_struct_condition_index_and_value
|
|||
subscription_manager = ContractAgency.get_agent(
|
||||
SubscriptionManagerAgent,
|
||||
registry=test_registry,
|
||||
provider_uri=TEST_POLYGON_PROVIDER_URI,
|
||||
blockchain_endpoint=TEST_POLYGON_PROVIDER_URI,
|
||||
)
|
||||
|
||||
# test "sponsor" index not equal to correct value
|
||||
|
|
|
@ -11,8 +11,11 @@ from nucypher.blockchain.eth.agents import (
|
|||
TACoApplicationAgent,
|
||||
TACoChildApplicationAgent,
|
||||
)
|
||||
from nucypher.blockchain.eth.domains import (
|
||||
DomainInfo,
|
||||
TACoDomain,
|
||||
)
|
||||
from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory
|
||||
from nucypher.blockchain.eth.networks import NetworksInventory
|
||||
from nucypher.blockchain.eth.registry import ContractRegistry, RegistrySourceManager
|
||||
from nucypher.blockchain.eth.signers.software import Web3Signer
|
||||
from nucypher.config.constants import TEMPORARY_DOMAIN
|
||||
|
@ -25,6 +28,7 @@ from tests.constants import (
|
|||
MIN_OPERATOR_SECONDS,
|
||||
TEST_ETH_PROVIDER_URI,
|
||||
TESTERCHAIN_CHAIN_ID,
|
||||
TESTERCHAIN_CHAIN_INFO,
|
||||
)
|
||||
from tests.utils.blockchain import TesterBlockchain
|
||||
from tests.utils.registry import ApeRegistrySource
|
||||
|
@ -299,8 +303,8 @@ def deployed_contracts(
|
|||
|
||||
|
||||
@pytest.fixture(scope="module", autouse=True)
|
||||
def test_registry(deployed_contracts):
|
||||
with tests.utils.registry.mock_registry_sources():
|
||||
def test_registry(deployed_contracts, module_mocker):
|
||||
with tests.utils.registry.mock_registry_sources(mocker=module_mocker):
|
||||
RegistrySourceManager._FALLBACK_CHAIN = (ApeRegistrySource,)
|
||||
source = ApeRegistrySource(domain=TEMPORARY_DOMAIN)
|
||||
registry = ContractRegistry(source=source)
|
||||
|
@ -312,7 +316,7 @@ def test_registry(deployed_contracts):
|
|||
def testerchain(project) -> TesterBlockchain:
|
||||
# Extract the web3 provider containing EthereumTester from the ape project's chain manager
|
||||
provider = project.chain_manager.provider.web3.provider
|
||||
testerchain = TesterBlockchain(eth_provider=provider)
|
||||
testerchain = TesterBlockchain(provider=provider)
|
||||
BlockchainInterfaceFactory.register_interface(interface=testerchain, force=True)
|
||||
yield testerchain
|
||||
|
||||
|
@ -370,7 +374,9 @@ def staking_providers(
|
|||
def coordinator_agent(testerchain, test_registry):
|
||||
"""Creates a coordinator agent"""
|
||||
coordinator = ContractAgency.get_agent(
|
||||
CoordinatorAgent, registry=test_registry, provider_uri=TEST_ETH_PROVIDER_URI
|
||||
CoordinatorAgent,
|
||||
registry=test_registry,
|
||||
blockchain_endpoint=TEST_ETH_PROVIDER_URI,
|
||||
)
|
||||
return coordinator
|
||||
|
||||
|
@ -380,7 +386,7 @@ def taco_application_agent(test_registry):
|
|||
_taco_application_agent = ContractAgency.get_agent(
|
||||
TACoApplicationAgent,
|
||||
registry=test_registry,
|
||||
provider_uri=TEST_ETH_PROVIDER_URI,
|
||||
blockchain_endpoint=TEST_ETH_PROVIDER_URI,
|
||||
)
|
||||
|
||||
return _taco_application_agent
|
||||
|
@ -391,7 +397,7 @@ def taco_child_application_agent(testerchain, test_registry):
|
|||
_taco_child_application_agent = ContractAgency.get_agent(
|
||||
TACoChildApplicationAgent,
|
||||
registry=test_registry,
|
||||
provider_uri=TEST_ETH_PROVIDER_URI,
|
||||
blockchain_endpoint=TEST_ETH_PROVIDER_URI,
|
||||
)
|
||||
|
||||
return _taco_child_application_agent
|
||||
|
@ -426,20 +432,20 @@ def multichain_ursulas(ursulas, multichain_ids, mock_rpc_condition):
|
|||
return ursulas
|
||||
|
||||
|
||||
@pytest.fixture(scope="session", autouse=True)
|
||||
def mock_condition_blockchains(session_mocker):
|
||||
@pytest.fixture(scope="module", autouse=True)
|
||||
def mock_condition_blockchains(module_mocker):
|
||||
"""adds testerchain's chain ID to permitted conditional chains"""
|
||||
session_mocker.patch.dict(
|
||||
module_mocker.patch.dict(
|
||||
"nucypher.policy.conditions.evm._CONDITION_CHAINS",
|
||||
{TESTERCHAIN_CHAIN_ID: "eth-tester/pyevm"},
|
||||
)
|
||||
|
||||
session_mocker.patch.object(
|
||||
NetworksInventory, "get_polygon_chain_id", return_value=TESTERCHAIN_CHAIN_ID
|
||||
test_domain_info = DomainInfo(
|
||||
TEMPORARY_DOMAIN, TESTERCHAIN_CHAIN_INFO, TESTERCHAIN_CHAIN_INFO
|
||||
)
|
||||
|
||||
session_mocker.patch.object(
|
||||
NetworksInventory, "get_ethereum_chain_id", return_value=TESTERCHAIN_CHAIN_ID
|
||||
module_mocker.patch.object(
|
||||
TACoDomain, "get_domain_info", return_value=test_domain_info
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
import pytest
|
||||
|
||||
from nucypher.blockchain.eth.clients import EthereumClient
|
||||
from nucypher.blockchain.eth.signers.software import Web3Signer
|
||||
from nucypher.crypto.powers import TransactingPower
|
||||
from tests.constants import (
|
||||
DEVELOPMENT_ETH_AIRDROP_AMOUNT,
|
||||
NUMBER_OF_ETH_TEST_ACCOUNTS,
|
||||
NUMBER_OF_STAKING_PROVIDERS_IN_BLOCKCHAIN_TESTS,
|
||||
NUMBER_OF_URSULAS_IN_BLOCKCHAIN_TESTS,
|
||||
)
|
||||
|
||||
# Prevents TesterBlockchain to be picked up by py.test as a test class
|
||||
from tests.utils.blockchain import TesterBlockchain as _TesterBlockchain
|
||||
|
||||
|
@ -28,7 +26,7 @@ def test_testerchain_creation(testerchain, another_testerchain):
|
|||
for chain in chains:
|
||||
|
||||
# Ensure we are testing on the correct network...
|
||||
assert 'tester' in chain.eth_provider_uri
|
||||
assert "tester" in chain.endpoint
|
||||
|
||||
# ... and that there are already some blocks mined
|
||||
chain.w3.eth.w3.testing.mine(1)
|
||||
|
|
|
@ -4,11 +4,19 @@ import pytest
|
|||
from eth_utils.crypto import keccak
|
||||
|
||||
from nucypher.blockchain.eth.actors import Operator
|
||||
from nucypher.blockchain.eth.networks import NetworksInventory
|
||||
from nucypher.blockchain.eth.domains import (
|
||||
DomainInfo,
|
||||
TACoDomain,
|
||||
)
|
||||
from nucypher.config.constants import TEMPORARY_DOMAIN
|
||||
from nucypher.crypto.powers import TransactingPower
|
||||
from nucypher.network.nodes import Learner
|
||||
from nucypher.utilities.logging import GlobalLoggerSettings
|
||||
from tests.constants import MOCK_IP_ADDRESS, TESTERCHAIN_CHAIN_ID
|
||||
from tests.constants import (
|
||||
MOCK_IP_ADDRESS,
|
||||
TESTERCHAIN_CHAIN_ID,
|
||||
TESTERCHAIN_CHAIN_INFO,
|
||||
)
|
||||
|
||||
# Don't re-lock accounts in the background while making commitments
|
||||
LOCK_FUNCTION = TransactingPower.lock_account
|
||||
|
@ -134,20 +142,19 @@ def disable_check_grant_requirements(session_mocker):
|
|||
session_mocker.patch(target, return_value=MOCK_IP_ADDRESS)
|
||||
|
||||
|
||||
@pytest.fixture(scope="session", autouse=True)
|
||||
def mock_condition_blockchains(session_mocker):
|
||||
@pytest.fixture(scope="module", autouse=True)
|
||||
def mock_condition_blockchains(module_mocker):
|
||||
"""adds testerchain's chain ID to permitted conditional chains"""
|
||||
session_mocker.patch.dict(
|
||||
module_mocker.patch.dict(
|
||||
"nucypher.policy.conditions.evm._CONDITION_CHAINS",
|
||||
{TESTERCHAIN_CHAIN_ID: "eth-tester/pyevm"},
|
||||
)
|
||||
|
||||
session_mocker.patch.object(
|
||||
NetworksInventory, "get_polygon_chain_id", return_value=TESTERCHAIN_CHAIN_ID
|
||||
test_domain_info = DomainInfo(
|
||||
TEMPORARY_DOMAIN, TESTERCHAIN_CHAIN_INFO, TESTERCHAIN_CHAIN_INFO
|
||||
)
|
||||
|
||||
session_mocker.patch.object(
|
||||
NetworksInventory, "get_ethereum_chain_id", return_value=TESTERCHAIN_CHAIN_ID
|
||||
module_mocker.patch.object(
|
||||
TACoDomain, "get_domain_info", return_value=test_domain_info
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ from random import SystemRandom
|
|||
from hexbytes import HexBytes
|
||||
from web3 import Web3
|
||||
|
||||
from nucypher.blockchain.eth.domains import ChainInfo
|
||||
from nucypher.blockchain.eth.token import NU
|
||||
from nucypher.config.constants import (
|
||||
NUCYPHER_ENVVAR_KEYSTORE_PASSWORD,
|
||||
|
@ -37,7 +38,7 @@ NUMBER_OF_STAKING_PROVIDERS_IN_BLOCKCHAIN_TESTS = NUMBER_OF_URSULAS_IN_BLOCKCHAI
|
|||
# Ursulas (Operators) and Staking Providers have their own account
|
||||
NUMBER_OF_ETH_TEST_ACCOUNTS = NUMBER_OF_URSULAS_IN_BLOCKCHAIN_TESTS + NUMBER_OF_STAKING_PROVIDERS_IN_BLOCKCHAIN_TESTS + 10
|
||||
|
||||
NUMBER_OF_URSULAS_IN_DEVELOPMENT_NETWORK = NUMBER_OF_URSULAS_IN_BLOCKCHAIN_TESTS
|
||||
NUMBER_OF_URSULAS_IN_DEVELOPMENT_DOMAIN = NUMBER_OF_URSULAS_IN_BLOCKCHAIN_TESTS
|
||||
|
||||
#
|
||||
# Local Signer Keystore
|
||||
|
@ -71,6 +72,8 @@ NUMBER_OF_ALLOCATIONS_IN_TESTS = 50 # TODO: Move to constants
|
|||
|
||||
TESTERCHAIN_CHAIN_ID = 131277322940537
|
||||
|
||||
TESTERCHAIN_CHAIN_INFO = ChainInfo(131277322940537, "eth-tester")
|
||||
|
||||
|
||||
#
|
||||
# Insecure Secrets
|
||||
|
|
|
@ -23,7 +23,6 @@ from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory
|
|||
from nucypher.blockchain.eth.signers.software import KeystoreSigner
|
||||
from nucypher.blockchain.eth.trackers.dkg import EventScannerTask
|
||||
from nucypher.characters.lawful import Enrico, Ursula
|
||||
from nucypher.config.base import CharacterConfiguration
|
||||
from nucypher.config.characters import (
|
||||
AliceConfiguration,
|
||||
BobConfiguration,
|
||||
|
@ -130,8 +129,8 @@ def random_address(random_account):
|
|||
@pytest.fixture(scope="module")
|
||||
def ursula_test_config(test_registry, temp_dir_path, testerchain):
|
||||
config = make_ursula_test_configuration(
|
||||
eth_provider_uri=TEST_ETH_PROVIDER_URI,
|
||||
pre_payment_provider=TEST_ETH_PROVIDER_URI,
|
||||
eth_endpoint=TEST_ETH_PROVIDER_URI,
|
||||
polygon_endpoint=TEST_ETH_PROVIDER_URI,
|
||||
test_registry=test_registry,
|
||||
rest_port=select_test_port(),
|
||||
operator_address=testerchain.ursulas_accounts.pop(),
|
||||
|
@ -145,8 +144,8 @@ def ursula_test_config(test_registry, temp_dir_path, testerchain):
|
|||
@pytest.fixture(scope="module")
|
||||
def alice_test_config(ursulas, testerchain, test_registry):
|
||||
config = make_alice_test_configuration(
|
||||
eth_provider_uri=TEST_ETH_PROVIDER_URI,
|
||||
pre_payment_provider=TEST_ETH_PROVIDER_URI,
|
||||
eth_endpoint=TEST_ETH_PROVIDER_URI,
|
||||
polygon_endpoint=TEST_ETH_PROVIDER_URI,
|
||||
known_nodes=ursulas,
|
||||
checksum_address=testerchain.alice_account,
|
||||
test_registry=test_registry,
|
||||
|
@ -157,9 +156,11 @@ def alice_test_config(ursulas, testerchain, test_registry):
|
|||
|
||||
@pytest.fixture(scope="module")
|
||||
def bob_test_config(testerchain, test_registry):
|
||||
config = make_bob_test_configuration(eth_provider_uri=TEST_ETH_PROVIDER_URI,
|
||||
test_registry=test_registry,
|
||||
checksum_address=testerchain.bob_account)
|
||||
config = make_bob_test_configuration(
|
||||
eth_endpoint=TEST_ETH_PROVIDER_URI,
|
||||
test_registry=test_registry,
|
||||
checksum_address=testerchain.bob_account,
|
||||
)
|
||||
yield config
|
||||
config.cleanup()
|
||||
|
||||
|
@ -197,7 +198,7 @@ def enacted_policy(idle_policy, ursulas):
|
|||
# cannot set them again
|
||||
# deposit = NON_PAYMENT(b"0000000")
|
||||
# contract_end_datetime = maya.now() + datetime.timedelta(days=5)
|
||||
network_middleware = MockRestMiddleware(eth_provider_uri=TEST_ETH_PROVIDER_URI)
|
||||
network_middleware = MockRestMiddleware(eth_endpoint=TEST_ETH_PROVIDER_URI)
|
||||
|
||||
# REST call happens here, as does population of TreasureMap.
|
||||
enacted_policy = idle_policy.enact(
|
||||
|
@ -262,8 +263,7 @@ def alice(alice_test_config, ursulas, testerchain):
|
|||
@pytest.fixture(scope="module")
|
||||
def bob(bob_test_config, testerchain):
|
||||
bob = bob_test_config.produce(
|
||||
coordinator_provider_uri=MOCK_ETH_PROVIDER_URI,
|
||||
coordinator_network=TEMPORARY_DOMAIN,
|
||||
polygon_endpoint=TEST_ETH_PROVIDER_URI,
|
||||
)
|
||||
yield bob
|
||||
bob.disenchant()
|
||||
|
@ -304,8 +304,8 @@ def lonely_ursula_maker(ursula_test_config, testerchain):
|
|||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def mock_registry_sources():
|
||||
with tests.utils.registry.mock_registry_sources():
|
||||
def mock_registry_sources(module_mocker):
|
||||
with tests.utils.registry.mock_registry_sources(module_mocker):
|
||||
yield
|
||||
|
||||
|
||||
|
@ -323,8 +323,7 @@ def light_ursula(temp_dir_path, random_account, mocker):
|
|||
KeystoreSigner, "_KeystoreSigner__get_signer", return_value=random_account
|
||||
)
|
||||
pre_payment_method = SubscriptionManagerPayment(
|
||||
eth_provider=MOCK_ETH_PROVIDER_URI,
|
||||
network=TEMPORARY_DOMAIN,
|
||||
blockchain_endpoint=MOCK_ETH_PROVIDER_URI, domain=TEMPORARY_DOMAIN
|
||||
)
|
||||
|
||||
mocker.patch.object(
|
||||
|
@ -338,7 +337,8 @@ def light_ursula(temp_dir_path, random_account, mocker):
|
|||
pre_payment_method=pre_payment_method,
|
||||
checksum_address=random_account.address,
|
||||
operator_address=random_account.address,
|
||||
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
|
||||
eth_endpoint=MOCK_ETH_PROVIDER_URI,
|
||||
polygon_endpoint=MOCK_ETH_PROVIDER_URI,
|
||||
signer=KeystoreSigner(path=temp_dir_path),
|
||||
)
|
||||
return ursula
|
||||
|
@ -434,17 +434,13 @@ def highperf_mocked_alice(
|
|||
monkeymodule,
|
||||
testerchain,
|
||||
):
|
||||
monkeymodule.setattr(
|
||||
CharacterConfiguration, "DEFAULT_PRE_PAYMENT_NETWORK", TEMPORARY_DOMAIN
|
||||
)
|
||||
|
||||
config = AliceConfiguration(
|
||||
dev_mode=True,
|
||||
domain=TEMPORARY_DOMAIN,
|
||||
eth_provider_uri=TEST_ETH_PROVIDER_URI,
|
||||
eth_endpoint=TEST_ETH_PROVIDER_URI,
|
||||
checksum_address=testerchain.alice_account,
|
||||
network_middleware=MockRestMiddlewareForLargeFleetTests(
|
||||
eth_provider_uri=TEST_ETH_PROVIDER_URI
|
||||
eth_endpoint=TEST_ETH_PROVIDER_URI
|
||||
),
|
||||
abort_on_learning_error=True,
|
||||
save_metadata=False,
|
||||
|
@ -462,10 +458,10 @@ def highperf_mocked_alice(
|
|||
def highperf_mocked_bob(fleet_of_highperf_mocked_ursulas):
|
||||
config = BobConfiguration(
|
||||
dev_mode=True,
|
||||
eth_provider_uri=TEST_ETH_PROVIDER_URI,
|
||||
eth_endpoint=TEST_ETH_PROVIDER_URI,
|
||||
domain=TEMPORARY_DOMAIN,
|
||||
network_middleware=MockRestMiddlewareForLargeFleetTests(
|
||||
eth_provider_uri=TEST_ETH_PROVIDER_URI
|
||||
eth_endpoint=TEST_ETH_PROVIDER_URI
|
||||
),
|
||||
abort_on_learning_error=True,
|
||||
save_metadata=False,
|
||||
|
@ -501,9 +497,8 @@ def click_runner():
|
|||
def nominal_configuration_fields():
|
||||
config = UrsulaConfiguration(
|
||||
dev_mode=True,
|
||||
pre_payment_network=TEMPORARY_DOMAIN,
|
||||
domain=TEMPORARY_DOMAIN,
|
||||
eth_provider_uri=TEST_ETH_PROVIDER_URI,
|
||||
eth_endpoint=TEST_ETH_PROVIDER_URI,
|
||||
)
|
||||
config_fields = config.static_payload()
|
||||
yield tuple(config_fields.keys())
|
||||
|
@ -565,7 +560,7 @@ def basic_auth_file(temp_dir_path):
|
|||
|
||||
@pytest.fixture(scope='module')
|
||||
def mock_rest_middleware():
|
||||
return MockRestMiddleware(eth_provider_uri=TEST_ETH_PROVIDER_URI)
|
||||
return MockRestMiddleware(eth_endpoint=TEST_ETH_PROVIDER_URI)
|
||||
|
||||
|
||||
#
|
||||
|
|
|
@ -83,9 +83,7 @@ def test_use_external_cache(enacted_policy, bob, ursulas):
|
|||
ursulas = list(ursulas)
|
||||
|
||||
# All Ursulas are down except for two
|
||||
bob.network_middleware = NodeIsDownMiddleware(
|
||||
eth_provider_uri=MOCK_ETH_PROVIDER_URI
|
||||
)
|
||||
bob.network_middleware = NodeIsDownMiddleware(eth_endpoint=MOCK_ETH_PROVIDER_URI)
|
||||
for ursula in ursulas[2:]:
|
||||
bob.network_middleware.node_is_down(ursula)
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ from nucypher.characters.lawful import Bob, Enrico
|
|||
from nucypher.config.constants import TEMPORARY_DOMAIN
|
||||
from tests.constants import (
|
||||
MOCK_ETH_PROVIDER_URI,
|
||||
NUMBER_OF_URSULAS_IN_DEVELOPMENT_NETWORK,
|
||||
NUMBER_OF_URSULAS_IN_DEVELOPMENT_DOMAIN,
|
||||
)
|
||||
from tests.utils.middleware import MockRestMiddleware
|
||||
|
||||
|
@ -49,8 +49,8 @@ def test_bob_retrieves(alice, ursulas, certificates_tempdir):
|
|||
bob = Bob(
|
||||
domain=TEMPORARY_DOMAIN,
|
||||
start_learning_now=True,
|
||||
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
|
||||
network_middleware=MockRestMiddleware(eth_provider_uri=MOCK_ETH_PROVIDER_URI),
|
||||
eth_endpoint=MOCK_ETH_PROVIDER_URI,
|
||||
network_middleware=MockRestMiddleware(eth_endpoint=MOCK_ETH_PROVIDER_URI),
|
||||
abort_on_learning_error=True,
|
||||
known_nodes=a_couple_of_ursulas,
|
||||
)
|
||||
|
@ -60,7 +60,7 @@ def test_bob_retrieves(alice, ursulas, certificates_tempdir):
|
|||
|
||||
# Alice creates a policy granting access to Bob
|
||||
# Just for fun, let's assume she distributes KFrags among Ursulas unknown to Bob
|
||||
shares = NUMBER_OF_URSULAS_IN_DEVELOPMENT_NETWORK - 2
|
||||
shares = NUMBER_OF_URSULAS_IN_DEVELOPMENT_DOMAIN - 2
|
||||
label = b'label://' + os.urandom(32)
|
||||
contract_end_datetime = maya.now() + datetime.timedelta(days=5)
|
||||
policy = alice.grant(
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import pytest
|
||||
|
||||
from nucypher.blockchain.eth.domains import TACoDomain
|
||||
from nucypher.blockchain.eth.signers.software import Web3Signer
|
||||
from nucypher.characters.chaotic import (
|
||||
NiceGuyEddie,
|
||||
|
@ -22,8 +23,8 @@ def _attempt_decryption(BobClass, plaintext, testerchain):
|
|||
enrico = NiceGuyEddie(encrypting_key=trinket, signer=signer)
|
||||
bob = BobClass(
|
||||
registry=MOCK_REGISTRY_FILEPATH,
|
||||
domain="lynx",
|
||||
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
|
||||
domain=TACoDomain.LYNX.name,
|
||||
eth_endpoint=MOCK_ETH_PROVIDER_URI,
|
||||
)
|
||||
|
||||
definitely_false_condition = {
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import pytest
|
||||
|
||||
from nucypher.config.constants import TEMPORARY_DOMAIN
|
||||
|
||||
|
||||
def test_new_ursula_announces_herself(lonely_ursula_maker):
|
||||
ursula_in_a_house, ursula_with_a_mouse = lonely_ursula_maker(
|
||||
quantity=2, domain="useless_domain"
|
||||
quantity=2, domain=TEMPORARY_DOMAIN
|
||||
)
|
||||
|
||||
# Neither Ursula knows about the other.
|
||||
|
@ -36,8 +38,8 @@ def test_goerli_and_mumbai_as_conditions_providers(lonely_ursula_maker):
|
|||
with pytest.raises(NotImplementedError):
|
||||
_ursula_who_tries_to_connect_to_an_invalid_chain = lonely_ursula_maker(
|
||||
quantity=1,
|
||||
domain="useless_domain",
|
||||
condition_provider_uris={
|
||||
domain=TEMPORARY_DOMAIN,
|
||||
condition_blockchain_endpoints={
|
||||
INVALID_CHAIN_ID: "this is a provider URI, but it doesn't matter what we pass here because the chain_id is invalid."
|
||||
},
|
||||
)
|
||||
|
|
|
@ -12,9 +12,8 @@ from nucypher.blockchain.eth.clients import EthereumClient
|
|||
from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory
|
||||
from nucypher.blockchain.eth.signers import KeystoreSigner
|
||||
from nucypher.blockchain.eth.signers.software import Web3Signer
|
||||
from nucypher.blockchain.eth.token import NU
|
||||
from nucypher.cli.actions.select import select_client_account
|
||||
from nucypher.cli.literature import GENERIC_SELECT_ACCOUNT, NO_ETH_ACCOUNTS
|
||||
from nucypher.cli.literature import GENERIC_SELECT_ACCOUNT, NO_ACCOUNTS
|
||||
from nucypher.config.constants import TEMPORARY_DOMAIN
|
||||
from tests.constants import (
|
||||
MOCK_ETH_PROVIDER_URI,
|
||||
|
@ -33,7 +32,7 @@ def test_select_client_account(
|
|||
selected_account = select_client_account(
|
||||
emitter=test_emitter,
|
||||
signer=Web3Signer(testerchain.client),
|
||||
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
|
||||
polygon_endpoint=MOCK_ETH_PROVIDER_URI,
|
||||
)
|
||||
assert selected_account, "Account selection returned Falsy instead of an address"
|
||||
assert isinstance(selected_account, str), "Selection is not a str"
|
||||
|
@ -56,10 +55,10 @@ def test_select_client_account_with_no_accounts(
|
|||
select_client_account(
|
||||
emitter=test_emitter,
|
||||
signer=Web3Signer(testerchain.client),
|
||||
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
|
||||
polygon_endpoint=MOCK_ETH_PROVIDER_URI,
|
||||
)
|
||||
captured = capsys.readouterr()
|
||||
assert NO_ETH_ACCOUNTS in captured.out
|
||||
assert NO_ACCOUNTS in captured.out
|
||||
|
||||
|
||||
def test_select_client_account_ambiguous_source(
|
||||
|
@ -120,7 +119,9 @@ def test_select_client_account_valid_sources(
|
|||
# From pre-initialized Provider
|
||||
mock_stdin.line(str(selection))
|
||||
expected_account = testerchain.client.accounts[selection]
|
||||
selected_account = select_client_account(emitter=test_emitter, eth_provider_uri=MOCK_ETH_PROVIDER_URI)
|
||||
selected_account = select_client_account(
|
||||
emitter=test_emitter, polygon_endpoint=MOCK_ETH_PROVIDER_URI
|
||||
)
|
||||
assert selected_account == expected_account
|
||||
assert mock_stdin.empty()
|
||||
captured = capsys.readouterr()
|
||||
|
@ -136,7 +137,7 @@ def test_select_client_account_valid_sources(
|
|||
BlockchainInterfaceFactory, "get_interface", return_value=testerchain
|
||||
)
|
||||
selected_account = select_client_account(
|
||||
emitter=test_emitter, eth_provider_uri=MOCK_ETH_PROVIDER_URI
|
||||
emitter=test_emitter, polygon_endpoint=MOCK_ETH_PROVIDER_URI
|
||||
)
|
||||
assert selected_account == expected_account
|
||||
assert mock_stdin.empty()
|
||||
|
@ -144,15 +145,17 @@ def test_select_client_account_valid_sources(
|
|||
assert GENERIC_SELECT_ACCOUNT in captured.out and f"Selected {selection}" in captured.out
|
||||
|
||||
|
||||
@pytest.mark.skip('fix me')
|
||||
@pytest.mark.parametrize('selection,show_staking,show_eth,show_tokens,stake_info', (
|
||||
(0, True, True, True, []),
|
||||
(1, True, True, True, []),
|
||||
(5, True, True, True, []),
|
||||
(NUMBER_OF_ETH_TEST_ACCOUNTS-1, True, True, True, []),
|
||||
(0, False, True, True, []),
|
||||
(0, False, False, True, []),
|
||||
(0, False, False, False, []),
|
||||
@pytest.mark.skip("fix me")
|
||||
@pytest.mark.parametrize(
|
||||
"selection,show_staking,show_matic,stake_info",
|
||||
(
|
||||
(0, True, True, []),
|
||||
(1, True, True, []),
|
||||
(5, True, True, []),
|
||||
(NUMBER_OF_ETH_TEST_ACCOUNTS - 1, True, True, []),
|
||||
(0, False, True, []),
|
||||
(0, False, False, []),
|
||||
(0, False, False, []),
|
||||
),
|
||||
)
|
||||
def test_select_client_account_with_balance_display(
|
||||
|
@ -164,8 +167,7 @@ def test_select_client_account_with_balance_display(
|
|||
mock_token_agent,
|
||||
selection,
|
||||
show_staking,
|
||||
show_eth,
|
||||
show_tokens,
|
||||
show_matic,
|
||||
stake_info,
|
||||
):
|
||||
|
||||
|
@ -173,23 +175,27 @@ def test_select_client_account_with_balance_display(
|
|||
mock_staking_agent.get_all_stakes.return_value = stake_info
|
||||
|
||||
# Missing network kwarg with balance display active
|
||||
blockchain_read_required = any((show_staking, show_eth, show_tokens))
|
||||
blockchain_read_required = any((show_staking, show_matic))
|
||||
if blockchain_read_required:
|
||||
with pytest.raises(ValueError, match='Pass network name or registry; Got neither.'):
|
||||
select_client_account(emitter=test_emitter,
|
||||
show_eth_balance=show_eth,
|
||||
show_nu_balance=show_tokens,
|
||||
show_staking=show_staking,
|
||||
eth_provider_uri=MOCK_ETH_PROVIDER_URI)
|
||||
with pytest.raises(
|
||||
ValueError, match="Pass domain name or registry; Got neither."
|
||||
):
|
||||
select_client_account(
|
||||
emitter=test_emitter,
|
||||
show_matic_balance=show_matic,
|
||||
show_staking=show_staking,
|
||||
polygon_endpoint=MOCK_ETH_PROVIDER_URI,
|
||||
)
|
||||
|
||||
# Good selection
|
||||
mock_stdin.line(str(selection))
|
||||
selected_account = select_client_account(emitter=test_emitter,
|
||||
network=TEMPORARY_DOMAIN,
|
||||
show_eth_balance=show_eth,
|
||||
show_nu_balance=show_tokens,
|
||||
show_staking=show_staking,
|
||||
eth_provider_uri=MOCK_ETH_PROVIDER_URI)
|
||||
selected_account = select_client_account(
|
||||
emitter=test_emitter,
|
||||
domain=TEMPORARY_DOMAIN,
|
||||
show_matic_balance=show_matic,
|
||||
show_staking=show_staking,
|
||||
polygon_endpoint=MOCK_ETH_PROVIDER_URI,
|
||||
)
|
||||
|
||||
# check for accurate selection consistency with client index
|
||||
assert selected_account == testerchain.client.accounts[selection]
|
||||
|
@ -199,10 +205,8 @@ def test_select_client_account_with_balance_display(
|
|||
headers = ['Account']
|
||||
if show_staking:
|
||||
headers.append('Staking')
|
||||
if show_eth:
|
||||
headers.append('ETH')
|
||||
if show_tokens:
|
||||
headers.append('NU')
|
||||
if show_matic:
|
||||
headers.append("MATIC")
|
||||
|
||||
captured = capsys.readouterr()
|
||||
for column_name in headers:
|
||||
|
@ -211,11 +215,7 @@ def test_select_client_account_with_balance_display(
|
|||
for account in testerchain.client.accounts:
|
||||
assert account in captured.out
|
||||
|
||||
if show_tokens:
|
||||
balance = mock_token_agent.get_balance(address=account)
|
||||
assert str(NU.from_units(balance)) in captured.out
|
||||
|
||||
if show_eth:
|
||||
if show_matic:
|
||||
balance = testerchain.client.get_balance(account=account)
|
||||
assert str(Web3.from_wei(balance, 'ether')) in captured.out
|
||||
|
||||
|
|
|
@ -1,24 +1,18 @@
|
|||
import pytest
|
||||
|
||||
from nucypher.blockchain.eth.networks import NetworksInventory
|
||||
from nucypher.cli.actions.select import select_network
|
||||
from nucypher.blockchain.eth.domains import TACoDomain
|
||||
from nucypher.cli.actions.select import select_domain
|
||||
|
||||
__DOMAINS = TACoDomain.SUPPORTED_DOMAIN_NAMES
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"user_input", range(0, len(NetworksInventory.ETH_NETWORKS) - 1)
|
||||
)
|
||||
def test_select_network_cli_action_eth(test_emitter, capsys, mock_stdin, user_input):
|
||||
@pytest.mark.parametrize("user_input", range(0, len(__DOMAINS) - 1))
|
||||
def test_select_network_cli_action(test_emitter, capsys, mock_stdin, user_input: int):
|
||||
mock_stdin.line(str(user_input))
|
||||
selection = NetworksInventory.ETH_NETWORKS[user_input]
|
||||
result = select_network(emitter=test_emitter, network_type=NetworksInventory.ETH)
|
||||
selection = __DOMAINS[user_input]
|
||||
result = select_domain(emitter=test_emitter)
|
||||
assert result == selection
|
||||
assert result not in NetworksInventory.POLY_NETWORKS
|
||||
captured = capsys.readouterr()
|
||||
for name in NetworksInventory.ETH_NETWORKS:
|
||||
for name in __DOMAINS:
|
||||
assert name in captured.out
|
||||
assert mock_stdin.empty()
|
||||
|
||||
|
||||
def test_select_network_cli_action_neither(test_emitter):
|
||||
with pytest.raises(Exception):
|
||||
select_network(emitter=test_emitter, network_type="FAKE COIN")
|
||||
|
|
|
@ -5,7 +5,7 @@ import pytest
|
|||
|
||||
from nucypher.blockchain.eth.registry import ContractRegistry
|
||||
from nucypher.cli.main import nucypher_cli
|
||||
from nucypher.config.characters import CharacterConfiguration, UrsulaConfiguration
|
||||
from nucypher.config.characters import UrsulaConfiguration
|
||||
from nucypher.config.constants import (
|
||||
NUCYPHER_ENVVAR_KEYSTORE_PASSWORD,
|
||||
TEMPORARY_DOMAIN,
|
||||
|
@ -40,11 +40,11 @@ def test_initialize_via_cli(
|
|||
init_args = (
|
||||
command,
|
||||
"init",
|
||||
"--network",
|
||||
"--domain",
|
||||
TEMPORARY_DOMAIN,
|
||||
"--eth-provider",
|
||||
"--eth-endpoint",
|
||||
MOCK_ETH_PROVIDER_URI,
|
||||
"--pre-payment-provider",
|
||||
"--polygon-endpoint",
|
||||
TEST_ETH_PROVIDER_URI,
|
||||
"--config-root",
|
||||
str(custom_filepath.absolute()),
|
||||
|
@ -82,9 +82,6 @@ def test_reconfigure_via_cli(
|
|||
monkeypatch.setattr(
|
||||
ContractRegistry, "from_latest_publication", fake_get_latest_registry
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
CharacterConfiguration, "DEFAULT_PRE_PAYMENT_NETWORK", TEMPORARY_DOMAIN
|
||||
)
|
||||
|
||||
custom_config_filepath = custom_filepath / config_class.generate_filename()
|
||||
|
||||
|
@ -103,13 +100,18 @@ def test_reconfigure_via_cli(
|
|||
|
||||
# Read pre-edit state
|
||||
config = config_class.from_configuration_file(custom_config_filepath)
|
||||
assert config.eth_provider_uri != TEST_ETH_PROVIDER_URI
|
||||
assert config.eth_endpoint != TEST_ETH_PROVIDER_URI
|
||||
del config
|
||||
|
||||
# Write
|
||||
view_args = (config_class.CHARACTER_CLASS.__name__.lower(), 'config',
|
||||
'--config-file', str(custom_config_filepath.absolute()),
|
||||
'--eth-provider', TEST_ETH_PROVIDER_URI)
|
||||
view_args = (
|
||||
config_class.CHARACTER_CLASS.__name__.lower(),
|
||||
"config",
|
||||
"--config-file",
|
||||
str(custom_config_filepath.absolute()),
|
||||
"--eth-endpoint",
|
||||
TEST_ETH_PROVIDER_URI,
|
||||
)
|
||||
result = click_runner.invoke(nucypher_cli, view_args, env=ENV)
|
||||
assert result.exit_code == 0
|
||||
|
||||
|
@ -121,4 +123,4 @@ def test_reconfigure_via_cli(
|
|||
assert str(custom_filepath) in result.output
|
||||
|
||||
# After editing the fields have been updated
|
||||
assert config.eth_provider_uri == TEST_ETH_PROVIDER_URI
|
||||
assert config.eth_endpoint == TEST_ETH_PROVIDER_URI
|
||||
|
|
|
@ -62,15 +62,13 @@ def test_corrupted_configuration(
|
|||
init_args = (
|
||||
"ursula",
|
||||
"init",
|
||||
"--eth-provider",
|
||||
"--eth-endpoint",
|
||||
MOCK_ETH_PROVIDER_URI,
|
||||
"--pre-payment-provider",
|
||||
"--polygon-endpoint",
|
||||
TEST_POLYGON_PROVIDER_URI,
|
||||
"--operator-address",
|
||||
another_ursula,
|
||||
"--network",
|
||||
TEMPORARY_DOMAIN,
|
||||
"--pre-payment-network",
|
||||
"--domain",
|
||||
TEMPORARY_DOMAIN,
|
||||
"--rest-host",
|
||||
MOCK_IP_ADDRESS,
|
||||
|
@ -105,13 +103,11 @@ def test_corrupted_configuration(
|
|||
init_args = (
|
||||
"ursula",
|
||||
"init",
|
||||
"--network",
|
||||
"--domain",
|
||||
TEMPORARY_DOMAIN,
|
||||
"--pre-payment-network",
|
||||
TEMPORARY_DOMAIN,
|
||||
"--eth-provider",
|
||||
"--eth-endpoint",
|
||||
MOCK_ETH_PROVIDER_URI,
|
||||
"--pre-payment-provider",
|
||||
"--polygon-endpoint",
|
||||
TEST_POLYGON_PROVIDER_URI,
|
||||
"--operator-address",
|
||||
another_ursula,
|
||||
|
|
|
@ -34,11 +34,11 @@ def test_ursula_startup_ip_checkup(click_runner, mocker):
|
|||
args = (
|
||||
"ursula",
|
||||
"init",
|
||||
"--network",
|
||||
"--domain",
|
||||
TEMPORARY_DOMAIN,
|
||||
"--eth-provider",
|
||||
"--eth-endpoint",
|
||||
MOCK_ETH_PROVIDER_URI,
|
||||
"--pre-payment-provider",
|
||||
"--polygon-endpoint",
|
||||
TEST_POLYGON_PROVIDER_URI,
|
||||
"--force",
|
||||
)
|
||||
|
@ -52,12 +52,12 @@ def test_ursula_startup_ip_checkup(click_runner, mocker):
|
|||
args = (
|
||||
"ursula",
|
||||
"init",
|
||||
"--network",
|
||||
"--domain",
|
||||
TEMPORARY_DOMAIN,
|
||||
"--force",
|
||||
"--eth-provider",
|
||||
"--eth-endpoint",
|
||||
MOCK_ETH_PROVIDER_URI,
|
||||
"--pre-payment-provider",
|
||||
"--polygon-endpoint",
|
||||
TEST_POLYGON_PROVIDER_URI,
|
||||
)
|
||||
result = click_runner.invoke(
|
||||
|
@ -70,12 +70,12 @@ def test_ursula_startup_ip_checkup(click_runner, mocker):
|
|||
args = (
|
||||
"ursula",
|
||||
"init",
|
||||
"--network",
|
||||
"--domain",
|
||||
TEMPORARY_DOMAIN,
|
||||
"--force",
|
||||
"--eth-provider",
|
||||
"--eth-endpoint",
|
||||
MOCK_ETH_PROVIDER_URI,
|
||||
"--pre-payment-provider",
|
||||
"--polygon-endpoint",
|
||||
TEST_POLYGON_PROVIDER_URI,
|
||||
)
|
||||
result = click_runner.invoke(
|
||||
|
|
|
@ -11,7 +11,6 @@ from nucypher.cli.literature import (
|
|||
CONFIRM_IPV4_ADDRESS_QUESTION,
|
||||
REPEAT_FOR_CONFIRMATION,
|
||||
SELECT_OPERATOR_ACCOUNT,
|
||||
SELECT_PRE_PAYMENT_NETWORK,
|
||||
SUCCESSFUL_DESTRUCTION,
|
||||
)
|
||||
from nucypher.cli.main import nucypher_cli
|
||||
|
@ -58,21 +57,20 @@ def test_interactive_initialize_ursula(click_runner, mocker, tmpdir):
|
|||
init_args = (
|
||||
"ursula",
|
||||
"init",
|
||||
"--network",
|
||||
"--domain",
|
||||
TEMPORARY_DOMAIN,
|
||||
"--eth-provider",
|
||||
"--eth-endpoint",
|
||||
MOCK_ETH_PROVIDER_URI,
|
||||
"--pre-payment-provider",
|
||||
"--polygon-endpoint",
|
||||
MOCK_ETH_PROVIDER_URI,
|
||||
)
|
||||
|
||||
user_input = '0\n' + '0\n' + YES_ENTER + FAKE_PASSWORD_CONFIRMED
|
||||
result = click_runner.invoke(nucypher_cli, init_args, input=user_input, catch_exceptions=False)
|
||||
user_input = "0\n" + YES_ENTER + FAKE_PASSWORD_CONFIRMED
|
||||
result = click_runner.invoke(
|
||||
nucypher_cli, init_args, input=user_input, catch_exceptions=False
|
||||
)
|
||||
assert result.exit_code == 0, result.output
|
||||
|
||||
# Select network
|
||||
assert SELECT_PRE_PAYMENT_NETWORK in result.output
|
||||
|
||||
# Select account
|
||||
assert SELECT_OPERATOR_ACCOUNT in result.output
|
||||
|
||||
|
@ -92,7 +90,7 @@ def test_initialize_custom_configuration_root(
|
|||
init_args = (
|
||||
"ursula",
|
||||
"init",
|
||||
"--network",
|
||||
"--domain",
|
||||
TEMPORARY_DOMAIN,
|
||||
"--config-root",
|
||||
str(custom_filepath.absolute()),
|
||||
|
@ -100,12 +98,10 @@ def test_initialize_custom_configuration_root(
|
|||
MOCK_IP_ADDRESS,
|
||||
"--rest-port",
|
||||
deploy_port,
|
||||
"--eth-provider",
|
||||
"--eth-endpoint",
|
||||
MOCK_ETH_PROVIDER_URI,
|
||||
"--pre-payment-provider",
|
||||
"--polygon-endpoint",
|
||||
MOCK_ETH_PROVIDER_URI,
|
||||
"--pre-payment-network",
|
||||
TEMPORARY_DOMAIN,
|
||||
"--operator-address",
|
||||
testerchain.ursulas_accounts[0],
|
||||
)
|
||||
|
|
|
@ -48,15 +48,13 @@ def test_ursula_init_with_local_keystore_signer(
|
|||
"ursula",
|
||||
"init",
|
||||
# Layer 1
|
||||
"--network",
|
||||
"--domain",
|
||||
TEMPORARY_DOMAIN,
|
||||
"--eth-provider",
|
||||
testerchain.eth_provider_uri,
|
||||
"--eth-endpoint",
|
||||
testerchain.endpoint,
|
||||
# Layer 2
|
||||
"--pre-payment-network",
|
||||
TEMPORARY_DOMAIN,
|
||||
"--pre-payment-provider",
|
||||
testerchain.eth_provider_uri,
|
||||
"--polygon-endpoint",
|
||||
testerchain.endpoint,
|
||||
"--rest-host",
|
||||
MOCK_IP_ADDRESS,
|
||||
"--rest-port",
|
||||
|
|
|
@ -44,15 +44,13 @@ all_configurations = tuple(
|
|||
def test_development_character_configurations(
|
||||
character, configuration, mocker, testerchain
|
||||
):
|
||||
mocker.patch.object(
|
||||
CharacterConfiguration, "DEFAULT_PRE_PAYMENT_NETWORK", TEMPORARY_DOMAIN
|
||||
)
|
||||
params = dict(
|
||||
dev_mode=True,
|
||||
lonely=True,
|
||||
domain=TEMPORARY_DOMAIN,
|
||||
checksum_address=testerchain.unassigned_accounts[0],
|
||||
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
|
||||
eth_endpoint=MOCK_ETH_PROVIDER_URI,
|
||||
polygon_endpoint=MOCK_ETH_PROVIDER_URI,
|
||||
)
|
||||
if character is Ursula:
|
||||
params.update(dict(operator_address=testerchain.unassigned_accounts[0]))
|
||||
|
@ -103,7 +101,7 @@ def test_default_character_configuration_preservation(
|
|||
):
|
||||
configuration_class.DEFAULT_CONFIG_ROOT = Path("/tmp")
|
||||
fake_address = "0xdeadbeef"
|
||||
network = TEMPORARY_DOMAIN
|
||||
domain = TEMPORARY_DOMAIN
|
||||
|
||||
expected_filename = (
|
||||
f"{configuration_class.NAME}.{configuration_class._CONFIG_FILE_EXTENSION}"
|
||||
|
@ -125,22 +123,18 @@ def test_default_character_configuration_preservation(
|
|||
keystore.signing_public_key = SecretKey.random().public_key()
|
||||
character_config = configuration_class(
|
||||
checksum_address=fake_address,
|
||||
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
|
||||
domain=network,
|
||||
eth_endpoint=MOCK_ETH_PROVIDER_URI,
|
||||
domain=domain,
|
||||
rest_host=MOCK_IP_ADDRESS,
|
||||
pre_payment_provider=MOCK_ETH_PROVIDER_URI,
|
||||
policy_registry=test_registry,
|
||||
pre_payment_network=TEMPORARY_DOMAIN,
|
||||
polygon_endpoint=MOCK_ETH_PROVIDER_URI,
|
||||
keystore=keystore,
|
||||
)
|
||||
|
||||
else:
|
||||
character_config = configuration_class(
|
||||
checksum_address=fake_address,
|
||||
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
|
||||
domain=network,
|
||||
pre_payment_network=TEMPORARY_DOMAIN,
|
||||
policy_registry=test_registry,
|
||||
eth_endpoint=MOCK_ETH_PROVIDER_URI,
|
||||
domain=domain,
|
||||
)
|
||||
|
||||
generated_filepath = character_config.generate_filepath()
|
||||
|
@ -177,8 +171,8 @@ def test_ursula_development_configuration(testerchain):
|
|||
checksum_address=testerchain.unassigned_accounts[0],
|
||||
operator_address=testerchain.unassigned_accounts[1],
|
||||
domain=TEMPORARY_DOMAIN,
|
||||
pre_payment_network=TEMPORARY_DOMAIN,
|
||||
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
|
||||
eth_endpoint=MOCK_ETH_PROVIDER_URI,
|
||||
polygon_endpoint=MOCK_ETH_PROVIDER_URI,
|
||||
)
|
||||
assert config.is_me is True
|
||||
assert config.dev_mode is True
|
||||
|
|
|
@ -14,11 +14,10 @@ def test_alices_powers_are_persistent(ursulas, temp_dir_path, testerchain):
|
|||
# Create a non-learning AliceConfiguration
|
||||
config_root = temp_dir_path / 'nucypher-custom-alice-config'
|
||||
alice_config = AliceConfiguration(
|
||||
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
|
||||
eth_endpoint=MOCK_ETH_PROVIDER_URI,
|
||||
config_root=config_root,
|
||||
network_middleware=MockRestMiddleware(eth_provider_uri=MOCK_ETH_PROVIDER_URI),
|
||||
network_middleware=MockRestMiddleware(eth_endpoint=MOCK_ETH_PROVIDER_URI),
|
||||
domain=TEMPORARY_DOMAIN,
|
||||
pre_payment_network=TEMPORARY_DOMAIN,
|
||||
checksum_address=testerchain.alice_account,
|
||||
start_learning_now=False,
|
||||
save_metadata=False,
|
||||
|
@ -57,8 +56,8 @@ def test_alices_powers_are_persistent(ursulas, temp_dir_path, testerchain):
|
|||
bob = Bob(
|
||||
start_learning_now=False,
|
||||
domain=TEMPORARY_DOMAIN,
|
||||
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
|
||||
network_middleware=MockRestMiddleware(eth_provider_uri=MOCK_ETH_PROVIDER_URI),
|
||||
eth_endpoint=MOCK_ETH_PROVIDER_URI,
|
||||
network_middleware=MockRestMiddleware(eth_endpoint=MOCK_ETH_PROVIDER_URI),
|
||||
)
|
||||
|
||||
bob_policy = alice.grant(bob, label, threshold=threshold, shares=shares, expiration=policy_end_datetime)
|
||||
|
@ -81,7 +80,7 @@ def test_alices_powers_are_persistent(ursulas, temp_dir_path, testerchain):
|
|||
# A new Alice is restored from the configuration file
|
||||
new_alice_config = AliceConfiguration.from_configuration_file(
|
||||
filepath=alice_config_file,
|
||||
network_middleware=MockRestMiddleware(eth_provider_uri=MOCK_ETH_PROVIDER_URI),
|
||||
network_middleware=MockRestMiddleware(eth_endpoint=MOCK_ETH_PROVIDER_URI),
|
||||
start_learning_now=False,
|
||||
config_root=config_root,
|
||||
known_nodes=ursulas,
|
||||
|
@ -98,9 +97,9 @@ def test_alices_powers_are_persistent(ursulas, temp_dir_path, testerchain):
|
|||
# Bob's eldest brother, Roberto, appears too
|
||||
roberto = Bob(
|
||||
domain=TEMPORARY_DOMAIN,
|
||||
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
|
||||
eth_endpoint=MOCK_ETH_PROVIDER_URI,
|
||||
start_learning_now=False,
|
||||
network_middleware=MockRestMiddleware(eth_provider_uri=MOCK_ETH_PROVIDER_URI),
|
||||
network_middleware=MockRestMiddleware(eth_endpoint=MOCK_ETH_PROVIDER_URI),
|
||||
)
|
||||
|
||||
# Alice creates a new policy for Roberto. Note how all the parameters
|
||||
|
|
|
@ -74,25 +74,27 @@ def test_characters_use_keystore(temp_dir_path, testerchain):
|
|||
keystore.unlock(password=INSECURE_DEVELOPMENT_PASSWORD)
|
||||
|
||||
pre_payment_method = SubscriptionManagerPayment(
|
||||
eth_provider=MOCK_ETH_PROVIDER_URI, network=TEMPORARY_DOMAIN
|
||||
blockchain_endpoint=MOCK_ETH_PROVIDER_URI, domain=TEMPORARY_DOMAIN
|
||||
)
|
||||
|
||||
alice = Alice(
|
||||
start_learning_now=False,
|
||||
keystore=keystore,
|
||||
domain=TEMPORARY_DOMAIN,
|
||||
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
|
||||
eth_endpoint=MOCK_ETH_PROVIDER_URI,
|
||||
polygon_endpoint=MOCK_ETH_PROVIDER_URI,
|
||||
checksum_address=testerchain.alice_account,
|
||||
pre_payment_method=pre_payment_method,
|
||||
)
|
||||
Bob(
|
||||
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
|
||||
eth_endpoint=MOCK_ETH_PROVIDER_URI,
|
||||
start_learning_now=False,
|
||||
keystore=keystore,
|
||||
domain=TEMPORARY_DOMAIN,
|
||||
)
|
||||
Ursula(
|
||||
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
|
||||
eth_endpoint=MOCK_ETH_PROVIDER_URI,
|
||||
polygon_endpoint=MOCK_ETH_PROVIDER_URI,
|
||||
start_learning_now=False,
|
||||
keystore=keystore,
|
||||
rest_host=LOOPBACK_ADDRESS,
|
||||
|
@ -158,7 +160,7 @@ def test_ritualist(temp_dir_path, testerchain, dkg_public_key):
|
|||
keystore.unlock(password=INSECURE_DEVELOPMENT_PASSWORD)
|
||||
|
||||
pre_payment_method = SubscriptionManagerPayment(
|
||||
eth_provider=MOCK_ETH_PROVIDER_URI, network=TEMPORARY_DOMAIN
|
||||
blockchain_endpoint=MOCK_ETH_PROVIDER_URI, domain=TEMPORARY_DOMAIN
|
||||
)
|
||||
|
||||
ursula = Ursula(
|
||||
|
@ -170,7 +172,8 @@ def test_ritualist(temp_dir_path, testerchain, dkg_public_key):
|
|||
pre_payment_method=pre_payment_method,
|
||||
operator_address=testerchain.ursulas_accounts[0],
|
||||
signer=Web3Signer(testerchain.client),
|
||||
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
|
||||
eth_endpoint=MOCK_ETH_PROVIDER_URI,
|
||||
polygon_endpoint=MOCK_ETH_PROVIDER_URI,
|
||||
)
|
||||
|
||||
ritual_id = 23
|
||||
|
|
|
@ -35,7 +35,7 @@ class BaseTestNodeStorageBackends:
|
|||
assert ursula == node_from_storage, "Node storage {} failed".format(node_storage)
|
||||
|
||||
pre_payment_method = SubscriptionManagerPayment(
|
||||
eth_provider=MOCK_ETH_PROVIDER_URI, network=TEMPORARY_DOMAIN
|
||||
blockchain_endpoint=MOCK_ETH_PROVIDER_URI, domain=TEMPORARY_DOMAIN
|
||||
)
|
||||
|
||||
# Save more nodes
|
||||
|
@ -46,7 +46,8 @@ class BaseTestNodeStorageBackends:
|
|||
rest_port=select_test_port(),
|
||||
domain=TEMPORARY_DOMAIN,
|
||||
signer=signer,
|
||||
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
|
||||
eth_endpoint=MOCK_ETH_PROVIDER_URI,
|
||||
polygon_endpoint=MOCK_ETH_PROVIDER_URI,
|
||||
checksum_address=operator_addresses[i],
|
||||
operator_address=operator_addresses[i],
|
||||
pre_payment_method=pre_payment_method,
|
||||
|
|
|
@ -14,11 +14,14 @@ from nucypher.blockchain.eth.agents import (
|
|||
TACoChildApplicationAgent,
|
||||
)
|
||||
from nucypher.blockchain.eth.clients import EthereumClient
|
||||
from nucypher.blockchain.eth.domains import (
|
||||
DomainInfo,
|
||||
TACoDomain,
|
||||
)
|
||||
from nucypher.blockchain.eth.interfaces import (
|
||||
BlockchainInterface,
|
||||
BlockchainInterfaceFactory,
|
||||
)
|
||||
from nucypher.blockchain.eth.networks import NetworksInventory
|
||||
from nucypher.blockchain.eth.registry import (
|
||||
ContractRegistry,
|
||||
)
|
||||
|
@ -35,6 +38,7 @@ from tests.constants import (
|
|||
MOCK_KEYSTORE_PATH,
|
||||
NUMBER_OF_MOCK_KEYSTORE_ACCOUNTS,
|
||||
TESTERCHAIN_CHAIN_ID,
|
||||
TESTERCHAIN_CHAIN_INFO,
|
||||
)
|
||||
from tests.mock.interfaces import MockBlockchain
|
||||
from tests.mock.io import MockStdinWrapper
|
||||
|
@ -132,8 +136,8 @@ def mock_interface(module_mocker):
|
|||
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def test_registry():
|
||||
with mock_registry_sources():
|
||||
def test_registry(module_mocker):
|
||||
with mock_registry_sources(mocker=module_mocker):
|
||||
mock_source = MockRegistrySource(domain=TEMPORARY_DOMAIN)
|
||||
registry = ContractRegistry(source=mock_source)
|
||||
yield registry
|
||||
|
@ -278,20 +282,20 @@ def monkeypatch_get_staking_provider_from_operator(monkeymodule):
|
|||
)
|
||||
|
||||
|
||||
@pytest.fixture(scope="session", autouse=True)
|
||||
def mock_condition_blockchains(session_mocker):
|
||||
@pytest.fixture(scope="module", autouse=True)
|
||||
def mock_condition_blockchains(module_mocker):
|
||||
"""adds testerchain's chain ID to permitted conditional chains"""
|
||||
session_mocker.patch.dict(
|
||||
module_mocker.patch.dict(
|
||||
"nucypher.policy.conditions.evm._CONDITION_CHAINS",
|
||||
{TESTERCHAIN_CHAIN_ID: "eth-tester/pyevm"},
|
||||
)
|
||||
|
||||
session_mocker.patch.object(
|
||||
NetworksInventory, "get_polygon_chain_id", return_value=TESTERCHAIN_CHAIN_ID
|
||||
test_domain_info = DomainInfo(
|
||||
TEMPORARY_DOMAIN, TESTERCHAIN_CHAIN_INFO, TESTERCHAIN_CHAIN_INFO
|
||||
)
|
||||
|
||||
session_mocker.patch.object(
|
||||
NetworksInventory, "get_ethereum_chain_id", return_value=TESTERCHAIN_CHAIN_ID
|
||||
module_mocker.patch.object(
|
||||
TACoDomain, "get_domain_info", return_value=test_domain_info
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -2,46 +2,90 @@ from pathlib import Path
|
|||
|
||||
import pytest
|
||||
|
||||
import tests
|
||||
from nucypher.acumen.perception import FleetSensor
|
||||
from nucypher.blockchain.eth.registry import ContractRegistry
|
||||
from nucypher.characters.lawful import Ursula
|
||||
from nucypher.config.storages import LocalFileBasedNodeStorage
|
||||
from nucypher.network.nodes import TEACHER_NODES
|
||||
from tests.utils.registry import MockRegistrySource
|
||||
from tests.utils.ursula import make_ursulas
|
||||
|
||||
|
||||
@pytest.mark.skip
|
||||
def test_learner_learns_about_domains_separately(lonely_ursula_maker, caplog):
|
||||
hero_learner, other_first_domain_learner = lonely_ursula_maker(
|
||||
domain="nucypher1.test_suite", quantity=2
|
||||
)
|
||||
_nobody = lonely_ursula_maker(domain="nucypher1.test_suite", quantity=1).pop()
|
||||
other_first_domain_learner.remember_node(_nobody)
|
||||
@pytest.fixture(scope="module")
|
||||
def domain_1():
|
||||
return "domain_uno"
|
||||
|
||||
second_domain_learners = lonely_ursula_maker(domain="nucypher2.test_suite", know_each_other=True, quantity=3)
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def domain_2():
|
||||
return "domain_dos"
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def test_registry(module_mocker, domain_1, domain_2):
|
||||
with tests.utils.registry.mock_registry_sources(
|
||||
mocker=module_mocker, domain_names=[domain_1, domain_2]
|
||||
):
|
||||
# doesn't really matter what domain is used here
|
||||
registry = ContractRegistry(MockRegistrySource(domain=domain_1))
|
||||
yield registry
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def registry_1(domain_1, test_registry):
|
||||
return ContractRegistry(MockRegistrySource(domain=domain_1))
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def registry_2(domain_2, test_registry):
|
||||
return ContractRegistry(MockRegistrySource(domain=domain_2))
|
||||
|
||||
|
||||
def test_learner_learns_about_domains_separately(
|
||||
lonely_ursula_maker, domain_1, domain_2, registry_1, registry_2, caplog
|
||||
):
|
||||
hero_learner, other_first_domain_learner = lonely_ursula_maker(
|
||||
domain=domain_1,
|
||||
registry=registry_1,
|
||||
quantity=2,
|
||||
)
|
||||
_nobody = lonely_ursula_maker(
|
||||
domain=domain_1, registry=registry_1, quantity=1
|
||||
).pop()
|
||||
other_first_domain_learner.remember_node(_nobody, eager=True)
|
||||
|
||||
second_domain_learners = lonely_ursula_maker(
|
||||
domain=domain_2, registry=registry_2, know_each_other=True, quantity=3
|
||||
)
|
||||
|
||||
assert len(hero_learner.known_nodes) == 0
|
||||
|
||||
# Learn from a teacher in our domain.
|
||||
hero_learner.remember_node(other_first_domain_learner)
|
||||
hero_learner.remember_node(other_first_domain_learner, eager=True)
|
||||
hero_learner.start_learning_loop(now=True)
|
||||
hero_learner.learn_from_teacher_node()
|
||||
hero_learner.learn_from_teacher_node(eager=True)
|
||||
|
||||
# All domain 1 nodes
|
||||
assert len(hero_learner.known_nodes) == 2
|
||||
|
||||
# Learn about the second domain.
|
||||
hero_learner._current_teacher_node = second_domain_learners.pop()
|
||||
hero_learner.learn_from_teacher_node()
|
||||
hero_learner.learn_from_teacher_node(eager=True)
|
||||
|
||||
# All domain 1 nodes
|
||||
assert len(hero_learner.known_nodes) == 2
|
||||
|
||||
new_first_domain_learner = lonely_ursula_maker(domain="nucypher1.test_suite", quantity=1).pop()
|
||||
_new_second_domain_learner = lonely_ursula_maker(domain="nucypher2.test_suite", quantity=1).pop()
|
||||
new_first_domain_learner = lonely_ursula_maker(
|
||||
domain=domain_1, registry=registry_1, quantity=1
|
||||
).pop()
|
||||
_new_second_domain_learner = lonely_ursula_maker(
|
||||
domain=domain_2, registry=registry_2, quantity=1
|
||||
).pop()
|
||||
|
||||
new_first_domain_learner.remember_node(hero_learner)
|
||||
new_first_domain_learner.remember_node(hero_learner, eager=True)
|
||||
|
||||
new_first_domain_learner.learn_from_teacher_node()
|
||||
new_first_domain_learner.learn_from_teacher_node(eager=True)
|
||||
|
||||
# This node, in the first domain, didn't learn about the second domain.
|
||||
assert not set(second_domain_learners).intersection(new_first_domain_learner.known_nodes)
|
||||
|
@ -52,8 +96,9 @@ def test_learner_learns_about_domains_separately(lonely_ursula_maker, caplog):
|
|||
assert _nobody in new_first_domain_learner.known_nodes
|
||||
|
||||
|
||||
@pytest.mark.skip
|
||||
def test_learner_restores_metadata_from_storage(lonely_ursula_maker, tmpdir):
|
||||
def test_learner_restores_metadata_from_storage(
|
||||
lonely_ursula_maker, tmpdir, domain_1, domain_2
|
||||
):
|
||||
# Create a local file-based node storage
|
||||
root = tmpdir.mkdir("known_nodes")
|
||||
metadata = root.mkdir("metadata")
|
||||
|
@ -63,20 +108,24 @@ def test_learner_restores_metadata_from_storage(lonely_ursula_maker, tmpdir):
|
|||
storage_root=Path(root))
|
||||
|
||||
# Use the ursula maker with this storage so it's populated with nodes from one domain
|
||||
_some_ursulas = lonely_ursula_maker(domain="fistro",
|
||||
node_storage=old_storage,
|
||||
know_each_other=True,
|
||||
quantity=3,
|
||||
save_metadata=True)
|
||||
_some_ursulas = lonely_ursula_maker(
|
||||
domain=domain_1,
|
||||
node_storage=old_storage,
|
||||
know_each_other=True,
|
||||
quantity=3,
|
||||
save_metadata=True,
|
||||
)
|
||||
|
||||
# Create a pair of new learners in a different domain, using the previous storage, and learn from it
|
||||
new_learners = lonely_ursula_maker(domain="duodenal",
|
||||
node_storage=old_storage,
|
||||
quantity=2,
|
||||
know_each_other=True,
|
||||
save_metadata=False)
|
||||
new_learners = lonely_ursula_maker(
|
||||
domain=domain_2,
|
||||
node_storage=old_storage,
|
||||
quantity=2,
|
||||
know_each_other=True,
|
||||
save_metadata=False,
|
||||
)
|
||||
learner, buddy = new_learners
|
||||
buddy._Learner__known_nodes = FleetSensor(domain="fistro")
|
||||
buddy._Learner__known_nodes = FleetSensor(domain=domain_1)
|
||||
|
||||
# The learner shouldn't learn about any node from the first domain, since it's different.
|
||||
learner.learn_from_teacher_node()
|
||||
|
@ -88,13 +137,20 @@ def test_learner_restores_metadata_from_storage(lonely_ursula_maker, tmpdir):
|
|||
assert set(learner.known_nodes) == {buddy}
|
||||
|
||||
|
||||
@pytest.mark.skip
|
||||
def test_learner_ignores_stored_nodes_from_other_domains(
|
||||
lonely_ursula_maker, tmpdir, testerchain, ursula_test_config
|
||||
lonely_ursula_maker,
|
||||
domain_1,
|
||||
domain_2,
|
||||
registry_1,
|
||||
registry_2,
|
||||
tmpdir,
|
||||
testerchain,
|
||||
ursula_test_config,
|
||||
):
|
||||
learner, other_staker = make_ursulas(
|
||||
ursula_test_config,
|
||||
domain="call-it-mainnet",
|
||||
domain=domain_1,
|
||||
registry=registry_1,
|
||||
quantity=2,
|
||||
know_each_other=True,
|
||||
staking_provider_addresses=testerchain.stake_providers_accounts[:2],
|
||||
|
@ -103,7 +159,8 @@ def test_learner_ignores_stored_nodes_from_other_domains(
|
|||
|
||||
pest, *other_ursulas_from_the_wrong_side_of_the_tracks = make_ursulas(
|
||||
ursula_test_config,
|
||||
domain="i-dunno-testt-maybe",
|
||||
domain=domain_2,
|
||||
registry=registry_2,
|
||||
quantity=5,
|
||||
know_each_other=True,
|
||||
staking_provider_addresses=testerchain.stake_providers_accounts[2:],
|
||||
|
@ -131,26 +188,33 @@ def test_learner_ignores_stored_nodes_from_other_domains(
|
|||
assert pest not in other_staker.known_nodes # But not anymore.
|
||||
|
||||
|
||||
@pytest.mark.skip
|
||||
def test_learner_with_empty_storage_uses_fallback_nodes(lonely_ursula_maker, mocker):
|
||||
domain = "learner-domain"
|
||||
mocker.patch.dict(TEACHER_NODES, {domain: ("teacher-uri",)}, clear=True)
|
||||
def test_learner_with_empty_storage_uses_fallback_nodes(
|
||||
lonely_ursula_maker, domain_1, mocker
|
||||
):
|
||||
mocker.patch.dict(TEACHER_NODES, {domain_1: ("teacher-uri",)}, clear=True)
|
||||
|
||||
# Create a learner and a teacher
|
||||
learner, teacher = lonely_ursula_maker(domain=domain, quantity=2, save_metadata=False)
|
||||
mocker.patch.object(Ursula, 'from_teacher_uri', return_value=teacher)
|
||||
learner, teacher = lonely_ursula_maker(
|
||||
domain=domain_1, quantity=2, save_metadata=False
|
||||
)
|
||||
mocker.patch.object(Ursula, "from_teacher_uri", return_value=teacher)
|
||||
|
||||
# Since there are no nodes in local node storage, the learner should only learn about the teacher
|
||||
learner.learn_from_teacher_node()
|
||||
assert set(learner.known_nodes) == {teacher}
|
||||
|
||||
|
||||
@pytest.mark.skip
|
||||
def test_learner_uses_both_nodes_from_storage_and_fallback_nodes(
|
||||
lonely_ursula_maker, tmpdir, mocker, test_registry, ursula_test_config, testerchain
|
||||
lonely_ursula_maker,
|
||||
domain_1,
|
||||
registry_1,
|
||||
tmpdir,
|
||||
mocker,
|
||||
test_registry,
|
||||
ursula_test_config,
|
||||
testerchain,
|
||||
):
|
||||
domain = "learner-domain"
|
||||
mocker.patch.dict(TEACHER_NODES, {domain: ("teacher-uri",)}, clear=True)
|
||||
mocker.patch.dict(TEACHER_NODES, {domain_1: ("teacher-uri",)}, clear=True)
|
||||
|
||||
# Create a local file-based node storage
|
||||
root = tmpdir.mkdir("known_nodes")
|
||||
|
@ -163,7 +227,8 @@ def test_learner_uses_both_nodes_from_storage_and_fallback_nodes(
|
|||
# Create some nodes and persist them to local storage
|
||||
other_nodes = make_ursulas(
|
||||
ursula_test_config,
|
||||
domain=domain,
|
||||
domain=domain_1,
|
||||
registry=registry_1,
|
||||
node_storage=node_storage,
|
||||
know_each_other=True,
|
||||
quantity=3,
|
||||
|
@ -174,7 +239,8 @@ def test_learner_uses_both_nodes_from_storage_and_fallback_nodes(
|
|||
|
||||
# Create a teacher and a learner using existing node storage
|
||||
learner, teacher = lonely_ursula_maker(
|
||||
domain=domain,
|
||||
domain=domain_1,
|
||||
registry=registry_1,
|
||||
node_storage=node_storage,
|
||||
quantity=2,
|
||||
know_each_other=True,
|
||||
|
|
|
@ -3,15 +3,18 @@ from functools import partial
|
|||
import pytest_twisted as pt
|
||||
from twisted.internet.threads import deferToThread
|
||||
|
||||
from nucypher.config.constants import TEMPORARY_DOMAIN
|
||||
from nucypher.network.middleware import RestMiddleware
|
||||
from tests.constants import MOCK_ETH_PROVIDER_URI
|
||||
|
||||
|
||||
def test_proper_seed_node_instantiation(lonely_ursula_maker):
|
||||
_lonely_ursula_maker = partial(lonely_ursula_maker, quantity=1)
|
||||
firstula = _lonely_ursula_maker(domain="this-is-meaningful-now").pop()
|
||||
firstula = _lonely_ursula_maker(domain=TEMPORARY_DOMAIN).pop()
|
||||
firstula_as_seed_node = firstula.seed_node_metadata()
|
||||
any_other_ursula = _lonely_ursula_maker(seed_nodes=[firstula_as_seed_node], domain="this-is-meaningful-now").pop()
|
||||
any_other_ursula = _lonely_ursula_maker(
|
||||
seed_nodes=[firstula_as_seed_node], domain=TEMPORARY_DOMAIN
|
||||
).pop()
|
||||
|
||||
assert not any_other_ursula.known_nodes
|
||||
any_other_ursula.start_learning_loop(now=True)
|
||||
|
@ -33,7 +36,7 @@ def test_get_cert_from_running_seed_node(lonely_ursula_maker):
|
|||
firstula_as_seed_node = firstula.seed_node_metadata()
|
||||
any_other_ursula = lonely_ursula_maker(
|
||||
seed_nodes=[firstula_as_seed_node],
|
||||
network_middleware=RestMiddleware(eth_provider_uri=MOCK_ETH_PROVIDER_URI),
|
||||
network_middleware=RestMiddleware(eth_endpoint=MOCK_ETH_PROVIDER_URI),
|
||||
).pop()
|
||||
assert not any_other_ursula.known_nodes
|
||||
|
||||
|
|
|
@ -20,9 +20,7 @@ def test_alice_can_grant_even_when_the_first_nodes_she_tries_are_down(
|
|||
label = b"this_is_the_path_to_which_access_is_being_granted"
|
||||
alice.known_nodes.current_state._nodes = {}
|
||||
|
||||
alice.network_middleware = NodeIsDownMiddleware(
|
||||
eth_provider_uri=MOCK_ETH_PROVIDER_URI
|
||||
)
|
||||
alice.network_middleware = NodeIsDownMiddleware(eth_endpoint=MOCK_ETH_PROVIDER_URI)
|
||||
|
||||
# OK, her first and only node is down.
|
||||
down_node = list(ursulas)[0]
|
||||
|
@ -78,9 +76,7 @@ def test_alice_can_grant_even_when_the_first_nodes_she_tries_are_down(
|
|||
|
||||
def test_node_has_changed_cert(alice, ursulas):
|
||||
alice.known_nodes.current_state._nodes = {}
|
||||
alice.network_middleware = NodeIsDownMiddleware(
|
||||
eth_provider_uri=MOCK_ETH_PROVIDER_URI
|
||||
)
|
||||
alice.network_middleware = NodeIsDownMiddleware(eth_endpoint=MOCK_ETH_PROVIDER_URI)
|
||||
alice.network_middleware.client.certs_are_broken = True
|
||||
|
||||
firstula = list(ursulas)[0]
|
||||
|
|
|
@ -67,7 +67,7 @@ def test_vladimir_illegal_interface_key_does_not_propagate(ursulas):
|
|||
|
||||
# This Ursula is totally legit...
|
||||
ursula_whom_vladimir_will_imitate.verify_node(
|
||||
MockRestMiddleware(eth_provider_uri=MOCK_ETH_PROVIDER_URI)
|
||||
MockRestMiddleware(eth_endpoint=MOCK_ETH_PROVIDER_URI)
|
||||
)
|
||||
|
||||
globalLogPublisher.addObserver(warning_trapper)
|
||||
|
|
|
@ -232,7 +232,7 @@ def test_join(join_worker_pool):
|
|||
assert t_end - t_start < 3
|
||||
|
||||
|
||||
class TestBatchValueFactory(BatchValueFactory):
|
||||
class BatchTrackingBatchValueFactory(BatchValueFactory):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.batch_sizes = []
|
||||
|
@ -258,7 +258,9 @@ def test_batched_value_generation(join_worker_pool):
|
|||
seed=123,
|
||||
)
|
||||
|
||||
factory = TestBatchValueFactory(values=list(outcomes), required_successes=10)
|
||||
factory = BatchTrackingBatchValueFactory(
|
||||
values=list(outcomes), required_successes=10
|
||||
)
|
||||
pool = WorkerPool(
|
||||
worker,
|
||||
factory,
|
||||
|
|
|
@ -70,7 +70,7 @@ def test_ursula_info_metrics_collector(test_registry, ursulas):
|
|||
|
||||
@pytest.mark.skipif(condition=(not PROMETHEUS_INSTALLED), reason="prometheus_client is required for test")
|
||||
def test_blockchain_metrics_collector(testerchain):
|
||||
collector = BlockchainMetricsCollector(eth_provider_uri=MOCK_ETH_PROVIDER_URI)
|
||||
collector = BlockchainMetricsCollector(eth_endpoint=MOCK_ETH_PROVIDER_URI)
|
||||
|
||||
collector_registry = CollectorRegistry()
|
||||
prefix = 'test_blockchain_metrics_collector'
|
||||
|
@ -96,7 +96,7 @@ def test_staking_provider_metrics_collector(test_registry, staking_providers):
|
|||
collector = StakingProviderMetricsCollector(
|
||||
staking_provider_address=staking_provider_address,
|
||||
contract_registry=test_registry,
|
||||
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
|
||||
eth_endpoint=MOCK_ETH_PROVIDER_URI,
|
||||
)
|
||||
collector_registry = CollectorRegistry()
|
||||
prefix = "test_staking_provider_metrics_collector"
|
||||
|
|
|
@ -22,6 +22,7 @@ from nucypher_core.umbral import SecretKey
|
|||
from web3 import Web3
|
||||
from web3.types import Wei
|
||||
|
||||
from nucypher.blockchain.eth.domains import LYNX
|
||||
from nucypher.blockchain.eth.signers import Signer
|
||||
from nucypher.characters.lawful import Alice, Bob, Ursula
|
||||
from nucypher.config.characters import AliceConfiguration
|
||||
|
@ -53,9 +54,9 @@ except KeyError:
|
|||
raise RuntimeError(message)
|
||||
|
||||
# Alice Configuration
|
||||
DOMAIN: str = 'mainnet' # tapir
|
||||
TACO_DOMAIN: str = LYNX.name # mainnet
|
||||
DEFAULT_SEEDNODE_URIS: List[str] = [
|
||||
*TEACHER_NODES[DOMAIN],
|
||||
*TEACHER_NODES[TACO_DOMAIN],
|
||||
]
|
||||
INSECURE_PASSWORD: str = "METRICS_INSECURE_DEVELOPMENT_PASSWORD"
|
||||
TEMP_ALICE_DIR: Path = Path('/', 'tmp', 'grant-metrics')
|
||||
|
@ -154,19 +155,19 @@ def make_alice(known_nodes: Optional[Set[Ursula]] = None):
|
|||
|
||||
# This is Alice's PRE payment method.
|
||||
pre_payment_method = SubscriptionManagerPayment(
|
||||
network='polygon',
|
||||
eth_provider=POLYGON_PROVIDER_URI
|
||||
domain=TACO_DOMAIN, blockchain_endpoint=POLYGON_PROVIDER_URI
|
||||
)
|
||||
|
||||
wallet = Signer.from_signer_uri(f'keystore://{SIGNER_URI}')
|
||||
wallet.unlock_account(account=ALICE_ADDRESS, password=SIGNER_PASSWORD)
|
||||
|
||||
alice_config = AliceConfiguration(
|
||||
eth_provider_uri=ETHEREUM_PROVIDER_URI,
|
||||
eth_endpoint=ETHEREUM_PROVIDER_URI,
|
||||
polygon_endpoint=POLYGON_PROVIDER_URI,
|
||||
checksum_address=ALICE_ADDRESS,
|
||||
signer_uri=f'keystore://{SIGNER_URI}',
|
||||
config_root=TEMP_ALICE_DIR,
|
||||
domain=DOMAIN,
|
||||
domain=TACO_DOMAIN,
|
||||
known_nodes=known_nodes,
|
||||
start_learning_now=False,
|
||||
learn_on_same_thread=True,
|
||||
|
@ -189,14 +190,14 @@ def setup():
|
|||
GlobalLoggerSettings.set_log_level('info')
|
||||
|
||||
|
||||
def aggregate_nodes(provider_uri: str) -> Tuple[Set[Ursula], Set[Ursula]]:
|
||||
def aggregate_nodes(eth_endpoint: str) -> Tuple[Set[Ursula], Set[Ursula]]:
|
||||
"""generates ursulas from URIs used in grant metrics collection"""
|
||||
|
||||
seednodes = set()
|
||||
if DEFAULT_SEEDNODE_URIS:
|
||||
for uri in DEFAULT_SEEDNODE_URIS:
|
||||
ursula = Ursula.from_seed_and_stake_info(
|
||||
seed_uri=uri, provider_uri=provider_uri
|
||||
seed_uri=uri, eth_endpoint=eth_endpoint
|
||||
)
|
||||
seednodes.add(ursula)
|
||||
|
||||
|
@ -204,7 +205,7 @@ def aggregate_nodes(provider_uri: str) -> Tuple[Set[Ursula], Set[Ursula]]:
|
|||
if HANDPICKED_URSULA_URIS:
|
||||
for uri in HANDPICKED_URSULA_URIS:
|
||||
ursula = Ursula.from_seed_and_stake_info(
|
||||
seed_uri=uri, provider_uri=provider_uri
|
||||
seed_uri=uri, eth_endpoint=eth_endpoint
|
||||
)
|
||||
ursulas.add(ursula)
|
||||
|
||||
|
@ -213,6 +214,6 @@ def aggregate_nodes(provider_uri: str) -> Tuple[Set[Ursula], Set[Ursula]]:
|
|||
|
||||
if __name__ == '__main__':
|
||||
setup()
|
||||
seednodes, ursulas = aggregate_nodes(provider_uri=ETHEREUM_PROVIDER_URI)
|
||||
seednodes, ursulas = aggregate_nodes(eth_endpoint=ETHEREUM_PROVIDER_URI)
|
||||
alice = make_alice(known_nodes=seednodes)
|
||||
collect(alice=alice, ursulas=ursulas)
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
|
||||
|
||||
|
||||
from typing import Union
|
||||
|
||||
from hexbytes import HexBytes
|
||||
|
|
|
@ -18,8 +18,8 @@ def pytest_addhooks(pluginmanager):
|
|||
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def test_registry():
|
||||
with mock_registry_sources():
|
||||
def test_registry(module_mocker):
|
||||
with mock_registry_sources(mocker=module_mocker):
|
||||
source = MockRegistrySource(domain=TEMPORARY_DOMAIN)
|
||||
yield ContractRegistry(source=source)
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ def test_actor_without_signing_power_cannot_sign():
|
|||
crypto_power=cannot_sign,
|
||||
start_learning_now=False,
|
||||
domain=TEMPORARY_DOMAIN,
|
||||
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
|
||||
eth_endpoint=MOCK_ETH_PROVIDER_URI,
|
||||
)
|
||||
|
||||
# The non-signer's stamp doesn't work for signing...
|
||||
|
@ -47,7 +47,7 @@ def test_actor_with_signing_power_can_sign():
|
|||
is_me=True,
|
||||
start_learning_now=False,
|
||||
domain=TEMPORARY_DOMAIN,
|
||||
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
|
||||
eth_endpoint=MOCK_ETH_PROVIDER_URI,
|
||||
)
|
||||
stamp_of_the_signer = signer.stamp
|
||||
|
||||
|
@ -73,14 +73,14 @@ def test_anybody_can_verify(random_address):
|
|||
domain=TEMPORARY_DOMAIN,
|
||||
checksum_address=random_address,
|
||||
pre_payment_method=FreeReencryptions(),
|
||||
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
|
||||
eth_endpoint=MOCK_ETH_PROVIDER_URI,
|
||||
)
|
||||
|
||||
# So, our story is fairly simple: an everyman meets Alice.
|
||||
somebody = Character(
|
||||
start_learning_now=False,
|
||||
domain=TEMPORARY_DOMAIN,
|
||||
eth_provider_uri=MOCK_ETH_PROVIDER_URI,
|
||||
eth_endpoint=MOCK_ETH_PROVIDER_URI,
|
||||
)
|
||||
|
||||
# Alice signs a message.
|
||||
|
|
|
@ -23,7 +23,7 @@ from nucypher.utilities.networking import (
|
|||
)
|
||||
from tests.constants import MOCK_ETH_PROVIDER_URI, MOCK_IP_ADDRESS
|
||||
|
||||
MOCK_NETWORK = 'holodeck'
|
||||
MOCK_DOMAIN = "holodeck"
|
||||
MOCK_PORT = 1111
|
||||
|
||||
|
||||
|
@ -33,7 +33,7 @@ class Dummy: # Teacher
|
|||
self.canonical_address = canonical_address
|
||||
self.checksum_address = to_checksum_address(canonical_address)
|
||||
self.certificate_filepath = None
|
||||
self.domain = MOCK_NETWORK
|
||||
self.domain = MOCK_DOMAIN
|
||||
|
||||
class GoodResponse:
|
||||
status_code = 200
|
||||
|
@ -96,7 +96,7 @@ def mock_client(mocker):
|
|||
|
||||
@pytest.fixture(autouse=True)
|
||||
def mock_default_teachers(mocker):
|
||||
teachers = {MOCK_NETWORK: (f"{MOCK_IP_ADDRESS}:{MOCK_PORT}", )}
|
||||
teachers = {MOCK_DOMAIN: (f"{MOCK_IP_ADDRESS}:{MOCK_PORT}",)}
|
||||
mocker.patch.dict(TEACHER_NODES, teachers, clear=True)
|
||||
|
||||
|
||||
|
@ -106,22 +106,22 @@ def test_get_external_ip_from_centralized_source(mock_requests):
|
|||
|
||||
|
||||
def test_get_external_ip_from_empty_known_nodes(mock_requests):
|
||||
sensor = FleetSensor(domain=MOCK_NETWORK)
|
||||
sensor = FleetSensor(domain=MOCK_DOMAIN)
|
||||
assert len(sensor) == 0
|
||||
get_external_ip_from_known_nodes(
|
||||
known_nodes=sensor, provider_uri=MOCK_ETH_PROVIDER_URI
|
||||
known_nodes=sensor, eth_endpoint=MOCK_ETH_PROVIDER_URI
|
||||
)
|
||||
# skipped because there are no known nodes
|
||||
mock_requests.assert_not_called()
|
||||
|
||||
|
||||
def test_get_external_ip_from_known_nodes_with_one_known_node(mock_requests):
|
||||
sensor = FleetSensor(domain=MOCK_NETWORK)
|
||||
sensor = FleetSensor(domain=MOCK_DOMAIN)
|
||||
sensor.record_node(Dummy(b'deadbeefdeadbeefdead'))
|
||||
sensor.record_fleet_state()
|
||||
assert len(sensor) == 1
|
||||
get_external_ip_from_known_nodes(
|
||||
known_nodes=sensor, provider_uri=MOCK_ETH_PROVIDER_URI
|
||||
known_nodes=sensor, eth_endpoint=MOCK_ETH_PROVIDER_URI
|
||||
)
|
||||
# skipped because there are too few known nodes
|
||||
mock_requests.assert_not_called()
|
||||
|
@ -130,7 +130,7 @@ def test_get_external_ip_from_known_nodes_with_one_known_node(mock_requests):
|
|||
def test_get_external_ip_from_known_nodes(mock_client):
|
||||
|
||||
# Setup FleetSensor
|
||||
sensor = FleetSensor(domain=MOCK_NETWORK)
|
||||
sensor = FleetSensor(domain=MOCK_DOMAIN)
|
||||
sample_size = 3
|
||||
sensor.record_node(Dummy(b'deadbeefdeadbeefdead'))
|
||||
sensor.record_node(Dummy(b'deadllamadeadllamade'))
|
||||
|
@ -140,7 +140,7 @@ def test_get_external_ip_from_known_nodes(mock_client):
|
|||
|
||||
# First sampled node replies
|
||||
get_external_ip_from_known_nodes(
|
||||
known_nodes=sensor, sample_size=sample_size, provider_uri=MOCK_ETH_PROVIDER_URI
|
||||
known_nodes=sensor, sample_size=sample_size, eth_endpoint=MOCK_ETH_PROVIDER_URI
|
||||
)
|
||||
assert mock_client.call_count == 1
|
||||
mock_client.call_count = 0 # reset
|
||||
|
@ -148,7 +148,7 @@ def test_get_external_ip_from_known_nodes(mock_client):
|
|||
# All sampled nodes dont respond
|
||||
mock_client.return_value = Dummy.BadResponse
|
||||
get_external_ip_from_known_nodes(
|
||||
known_nodes=sensor, sample_size=sample_size, provider_uri=MOCK_ETH_PROVIDER_URI
|
||||
known_nodes=sensor, sample_size=sample_size, eth_endpoint=MOCK_ETH_PROVIDER_URI
|
||||
)
|
||||
assert mock_client.call_count == sample_size
|
||||
|
||||
|
@ -156,7 +156,7 @@ def test_get_external_ip_from_known_nodes(mock_client):
|
|||
def test_get_external_ip_from_known_nodes_client(mocker, mock_client):
|
||||
|
||||
# Setup FleetSensor
|
||||
sensor = FleetSensor(domain=MOCK_NETWORK)
|
||||
sensor = FleetSensor(domain=MOCK_DOMAIN)
|
||||
sample_size = 3
|
||||
sensor.record_node(Dummy(b'deadbeefdeadbeefdead'))
|
||||
sensor.record_node(Dummy(b'deadllamadeadllamade'))
|
||||
|
@ -166,10 +166,10 @@ def test_get_external_ip_from_known_nodes_client(mocker, mock_client):
|
|||
|
||||
# Setup HTTP Client
|
||||
mocker.patch.object(Ursula, 'from_teacher_uri', return_value=Dummy(b'deadporkdeadporkdead'))
|
||||
teacher_uri = TEACHER_NODES[MOCK_NETWORK][0]
|
||||
teacher_uri = TEACHER_NODES[MOCK_DOMAIN][0]
|
||||
|
||||
get_external_ip_from_known_nodes(
|
||||
known_nodes=sensor, sample_size=sample_size, provider_uri=MOCK_ETH_PROVIDER_URI
|
||||
known_nodes=sensor, sample_size=sample_size, eth_endpoint=MOCK_ETH_PROVIDER_URI
|
||||
)
|
||||
assert mock_client.call_count == 1 # first node responded
|
||||
|
||||
|
@ -183,7 +183,7 @@ def test_get_external_ip_default_teacher_unreachable(mocker):
|
|||
# Default seednode is down
|
||||
mocker.patch.object(Ursula, "from_teacher_uri", side_effect=error)
|
||||
ip = get_external_ip_from_default_teacher(
|
||||
network=MOCK_NETWORK, provider_uri=MOCK_ETH_PROVIDER_URI
|
||||
domain=MOCK_DOMAIN, eth_endpoint=MOCK_ETH_PROVIDER_URI
|
||||
)
|
||||
assert ip is None
|
||||
|
||||
|
@ -191,12 +191,12 @@ def test_get_external_ip_default_teacher_unreachable(mocker):
|
|||
def test_get_external_ip_from_default_teacher(mocker, mock_client, mock_requests):
|
||||
|
||||
mock_client.return_value = Dummy.GoodResponse
|
||||
teacher_uri = TEACHER_NODES[MOCK_NETWORK][0]
|
||||
teacher_uri = TEACHER_NODES[MOCK_DOMAIN][0]
|
||||
mocker.patch.object(Ursula, 'from_teacher_uri', return_value=Dummy(b'deadbeefdeadbeefdead'))
|
||||
|
||||
# "Success"
|
||||
ip = get_external_ip_from_default_teacher(
|
||||
network=MOCK_NETWORK, provider_uri=MOCK_ETH_PROVIDER_URI
|
||||
domain=MOCK_DOMAIN, eth_endpoint=MOCK_ETH_PROVIDER_URI
|
||||
)
|
||||
assert ip == MOCK_IP_ADDRESS
|
||||
|
||||
|
@ -208,13 +208,13 @@ def test_get_external_ip_from_default_teacher(mocker, mock_client, mock_requests
|
|||
assert endpoint == f'https://{teacher_uri}/ping'
|
||||
|
||||
|
||||
def test_get_external_ip_default_unknown_network():
|
||||
def test_get_external_ip_default_unknown_domain():
|
||||
unknown_domain = 'thisisnotarealdomain'
|
||||
|
||||
# Without fleet sensor
|
||||
with pytest.raises(UnknownIPAddress):
|
||||
determine_external_ip_address(
|
||||
network=unknown_domain, provider_uri=MOCK_ETH_PROVIDER_URI
|
||||
domain=unknown_domain, eth_endpoint=MOCK_ETH_PROVIDER_URI
|
||||
)
|
||||
|
||||
# with fleet sensor
|
||||
|
@ -222,8 +222,8 @@ def test_get_external_ip_default_unknown_network():
|
|||
with pytest.raises(UnknownIPAddress):
|
||||
determine_external_ip_address(
|
||||
known_nodes=sensor,
|
||||
network=unknown_domain,
|
||||
provider_uri=MOCK_ETH_PROVIDER_URI,
|
||||
domain=unknown_domain,
|
||||
eth_endpoint=MOCK_ETH_PROVIDER_URI,
|
||||
)
|
||||
|
||||
|
||||
|
@ -232,13 +232,13 @@ def test_get_external_ip_cascade_failure(mocker, mock_requests):
|
|||
second = mocker.patch('nucypher.utilities.networking.get_external_ip_from_default_teacher', return_value=None)
|
||||
third = mocker.patch('nucypher.utilities.networking.get_external_ip_from_centralized_source', return_value=None)
|
||||
|
||||
sensor = FleetSensor(domain=MOCK_NETWORK)
|
||||
sensor = FleetSensor(domain=MOCK_DOMAIN)
|
||||
sensor.record_node(Dummy(b'deadbeefdeadbeefdead'))
|
||||
sensor.record_fleet_state()
|
||||
|
||||
with pytest.raises(UnknownIPAddress, match="External IP address detection failed"):
|
||||
determine_external_ip_address(
|
||||
network=MOCK_NETWORK, known_nodes=sensor, provider_uri=MOCK_ETH_PROVIDER_URI
|
||||
domain=MOCK_DOMAIN, known_nodes=sensor, eth_endpoint=MOCK_ETH_PROVIDER_URI
|
||||
)
|
||||
|
||||
first.assert_called_once()
|
||||
|
|
|
@ -10,7 +10,7 @@ from tests.mock.coordinator import MockCoordinatorAgent
|
|||
@pytest.fixture(scope="module")
|
||||
def agent(mock_contract_agency) -> MockCoordinatorAgent:
|
||||
coordinator_agent: CoordinatorAgent = mock_contract_agency.get_agent(
|
||||
CoordinatorAgent, registry=None, provider_uri=MOCK_ETH_PROVIDER_URI
|
||||
CoordinatorAgent, registry=None, blockchain_endpoint=MOCK_ETH_PROVIDER_URI
|
||||
)
|
||||
return coordinator_agent
|
||||
|
||||
|
|
|
@ -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")
|
|
@ -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
|
|
@ -1,13 +1,18 @@
|
|||
|
||||
|
||||
import datetime
|
||||
from unittest.mock import PropertyMock, Mock
|
||||
from unittest.mock import Mock, PropertyMock
|
||||
|
||||
import pytest
|
||||
from web3 import HTTPProvider, IPCProvider, WebsocketProvider
|
||||
|
||||
from nucypher.blockchain.eth.clients import (GanacheClient, GethClient, InfuraClient, PUBLIC_CHAINS,
|
||||
ParityClient, AlchemyClient)
|
||||
from nucypher.blockchain.eth.clients import (
|
||||
AlchemyClient,
|
||||
GanacheClient,
|
||||
GethClient,
|
||||
InfuraClient,
|
||||
ParityClient,
|
||||
)
|
||||
from nucypher.blockchain.eth.interfaces import BlockchainInterface
|
||||
from nucypher.utilities.networking import LOOPBACK_ADDRESS
|
||||
|
||||
|
@ -139,53 +144,53 @@ class ProviderTypeTestClient(BlockchainInterfaceTestBase):
|
|||
self.expected_provider_class = expected_provider_class
|
||||
self.test_provider_to_attach = actual_provider_to_attach
|
||||
|
||||
def _attach_eth_provider(self, *args, **kwargs) -> None:
|
||||
super()._attach_eth_provider(*args, **kwargs)
|
||||
def _attach_blockchain_provider(self, *args, **kwargs) -> None:
|
||||
super()._attach_blockchain_provider(*args, **kwargs)
|
||||
|
||||
# check type
|
||||
assert isinstance(self.provider, self.expected_provider_class)
|
||||
|
||||
super()._attach_eth_provider(eth_provider=self.test_provider_to_attach)
|
||||
super()._attach_blockchain_provider(provider=self.test_provider_to_attach)
|
||||
|
||||
|
||||
class InfuraTestClient(BlockchainInterfaceTestBase):
|
||||
|
||||
def _attach_eth_provider(self, *args, **kwargs) -> None:
|
||||
super()._attach_eth_provider(eth_provider=MockInfuraProvider())
|
||||
def _attach_blockchain_provider(self, *args, **kwargs) -> None:
|
||||
super()._attach_blockchain_provider(provider=MockInfuraProvider())
|
||||
|
||||
|
||||
class AlchemyTestClient(BlockchainInterfaceTestBase):
|
||||
|
||||
def _attach_eth_provider(self, *args, **kwargs) -> None:
|
||||
super()._attach_eth_provider(eth_provider=MockAlchemyProvider())
|
||||
def _attach_blockchain_provider(self, *args, **kwargs) -> None:
|
||||
super()._attach_blockchain_provider(provider=MockAlchemyProvider())
|
||||
|
||||
|
||||
class GethClientTestBlockchain(BlockchainInterfaceTestBase):
|
||||
|
||||
def _attach_eth_provider(self, *args, **kwargs) -> None:
|
||||
super()._attach_eth_provider(eth_provider=MockGethProvider())
|
||||
def _attach_blockchain_provider(self, *args, **kwargs) -> None:
|
||||
super()._attach_blockchain_provider(provider=MockGethProvider())
|
||||
|
||||
|
||||
class ParityClientTestInterface(BlockchainInterfaceTestBase):
|
||||
|
||||
def _attach_eth_provider(self, *args, **kwargs) -> None:
|
||||
super()._attach_eth_provider(eth_provider=MockParityProvider())
|
||||
def _attach_blockchain_provider(self, *args, **kwargs) -> None:
|
||||
super()._attach_blockchain_provider(provider=MockParityProvider())
|
||||
|
||||
|
||||
class GanacheClientTestInterface(BlockchainInterfaceTestBase):
|
||||
|
||||
def _attach_eth_provider(self, *args, **kwargs) -> None:
|
||||
super()._attach_eth_provider(eth_provider=MockGanacheProvider())
|
||||
def _attach_blockchain_provider(self, *args, **kwargs) -> None:
|
||||
super()._attach_blockchain_provider(provider=MockGanacheProvider())
|
||||
|
||||
|
||||
def test_client_no_provider():
|
||||
with pytest.raises(BlockchainInterface.NoProvider) as e:
|
||||
with pytest.raises(BlockchainInterface.NoProvider):
|
||||
interface = BlockchainInterfaceTestBase()
|
||||
interface.connect()
|
||||
|
||||
|
||||
def test_geth_web3_client():
|
||||
interface = GethClientTestBlockchain(eth_provider_uri='file:///ipc.geth')
|
||||
interface = GethClientTestBlockchain(endpoint="file:///ipc.geth")
|
||||
interface.connect()
|
||||
|
||||
assert isinstance(interface.client, GethClient)
|
||||
|
@ -199,62 +204,75 @@ def test_geth_web3_client():
|
|||
|
||||
|
||||
def test_autodetect_provider_type_file(tempfile_path):
|
||||
|
||||
interface = ProviderTypeTestClient(eth_provider_uri=str(tempfile_path), # existing file for test
|
||||
expected_provider_class=IPCProvider,
|
||||
actual_provider_to_attach=MockGethProvider())
|
||||
interface = ProviderTypeTestClient(
|
||||
endpoint=str(tempfile_path), # existing file for test
|
||||
expected_provider_class=IPCProvider,
|
||||
actual_provider_to_attach=MockGethProvider(),
|
||||
)
|
||||
interface.connect()
|
||||
assert isinstance(interface.client, GethClient)
|
||||
|
||||
|
||||
def test_autodetect_provider_type_file_none_existent():
|
||||
with pytest.raises(BlockchainInterface.UnsupportedProvider) as e:
|
||||
interface = BlockchainInterfaceTestBase(eth_provider_uri='/none_existent.ipc.geth')
|
||||
with pytest.raises(BlockchainInterface.UnsupportedProvider):
|
||||
interface = BlockchainInterfaceTestBase(endpoint="/none_existent.ipc.geth")
|
||||
interface.connect()
|
||||
|
||||
|
||||
def test_detect_provider_type_file():
|
||||
interface = ProviderTypeTestClient(eth_provider_uri='file:///ipc.geth',
|
||||
expected_provider_class=IPCProvider,
|
||||
actual_provider_to_attach=MockGethProvider())
|
||||
interface = ProviderTypeTestClient(
|
||||
endpoint="file:///ipc.geth",
|
||||
expected_provider_class=IPCProvider,
|
||||
actual_provider_to_attach=MockGethProvider(),
|
||||
)
|
||||
interface.connect()
|
||||
assert isinstance(interface.client, GethClient)
|
||||
|
||||
|
||||
def test_detect_provider_type_ipc():
|
||||
interface = ProviderTypeTestClient(eth_provider_uri='ipc:///ipc.geth',
|
||||
expected_provider_class=IPCProvider,
|
||||
actual_provider_to_attach=MockGethProvider())
|
||||
interface = ProviderTypeTestClient(
|
||||
endpoint="ipc:///ipc.geth",
|
||||
expected_provider_class=IPCProvider,
|
||||
actual_provider_to_attach=MockGethProvider(),
|
||||
)
|
||||
interface.connect()
|
||||
assert isinstance(interface.client, GethClient)
|
||||
|
||||
|
||||
def test_detect_provider_type_http():
|
||||
interface = ProviderTypeTestClient(eth_provider_uri='http://ganache:8445',
|
||||
expected_provider_class=HTTPProvider,
|
||||
actual_provider_to_attach=MockGanacheProvider())
|
||||
interface = ProviderTypeTestClient(
|
||||
endpoint="http://ganache:8445",
|
||||
expected_provider_class=HTTPProvider,
|
||||
actual_provider_to_attach=MockGanacheProvider(),
|
||||
)
|
||||
interface.connect()
|
||||
assert isinstance(interface.client, GanacheClient)
|
||||
|
||||
|
||||
def test_detect_provider_type_https():
|
||||
interface = ProviderTypeTestClient(eth_provider_uri='https://ganache:8445',
|
||||
expected_provider_class=HTTPProvider,
|
||||
actual_provider_to_attach=MockGanacheProvider())
|
||||
interface = ProviderTypeTestClient(
|
||||
endpoint="https://ganache:8445",
|
||||
expected_provider_class=HTTPProvider,
|
||||
actual_provider_to_attach=MockGanacheProvider(),
|
||||
)
|
||||
interface.connect()
|
||||
assert isinstance(interface.client, GanacheClient)
|
||||
|
||||
|
||||
def test_detect_provider_type_ws():
|
||||
interface = ProviderTypeTestClient(eth_provider_uri=f'ws://{LOOPBACK_ADDRESS}:8546',
|
||||
expected_provider_class=WebsocketProvider,
|
||||
actual_provider_to_attach=MockWebSocketProvider())
|
||||
interface = ProviderTypeTestClient(
|
||||
endpoint=f"ws://{LOOPBACK_ADDRESS}:8546",
|
||||
expected_provider_class=WebsocketProvider,
|
||||
actual_provider_to_attach=MockWebSocketProvider(),
|
||||
)
|
||||
interface.connect()
|
||||
assert isinstance(interface.client, GethClient)
|
||||
|
||||
|
||||
def test_infura_web3_client():
|
||||
interface = InfuraTestClient(eth_provider_uri='wss://:@goerli.infura.io/ws/v3/1234567890987654321abcdef')
|
||||
interface = InfuraTestClient(
|
||||
endpoint="wss://:@goerli.infura.io/ws/v3/1234567890987654321abcdef"
|
||||
)
|
||||
interface.connect()
|
||||
|
||||
assert isinstance(interface.client, InfuraClient)
|
||||
|
@ -270,7 +288,9 @@ def test_infura_web3_client():
|
|||
|
||||
|
||||
def test_alchemy_web3_client():
|
||||
interface = AlchemyTestClient(eth_provider_uri='https://eth-rinkeby.alchemyapi.io/v2/1234567890987654321abcdef')
|
||||
interface = AlchemyTestClient(
|
||||
endpoint="https://eth-rinkeby.alchemyapi.io/v2/1234567890987654321abcdef"
|
||||
)
|
||||
interface.connect()
|
||||
|
||||
assert isinstance(interface.client, AlchemyClient)
|
||||
|
@ -282,7 +302,7 @@ def test_alchemy_web3_client():
|
|||
|
||||
|
||||
def test_parity_web3_client():
|
||||
interface = ParityClientTestInterface(eth_provider_uri='file:///ipc.parity')
|
||||
interface = ParityClientTestInterface(endpoint="file:///ipc.parity")
|
||||
interface.connect()
|
||||
|
||||
assert isinstance(interface.client, ParityClient)
|
||||
|
@ -293,7 +313,7 @@ def test_parity_web3_client():
|
|||
|
||||
|
||||
def test_ganache_web3_client():
|
||||
interface = GanacheClientTestInterface(eth_provider_uri='http://ganache:8445')
|
||||
interface = GanacheClientTestInterface(endpoint="http://ganache:8445")
|
||||
interface.connect()
|
||||
|
||||
assert isinstance(interface.client, GanacheClient)
|
||||
|
|
|
@ -73,18 +73,23 @@ class TesterBlockchain(BlockchainInterface):
|
|||
__OPERATORS_RANGE = range(NUMBER_OF_URSULAS_IN_BLOCKCHAIN_TESTS)
|
||||
__ACCOUNT_CACHE = list()
|
||||
|
||||
def __init__(self,
|
||||
test_accounts: int = NUMBER_OF_ETH_TEST_ACCOUNTS,
|
||||
poa: bool = True,
|
||||
light: bool = False,
|
||||
eth_airdrop: bool = False,
|
||||
*args, **kwargs):
|
||||
|
||||
EXPECTED_CONFIRMATION_TIME_IN_SECONDS['free'] = 5 # Just some upper-limit
|
||||
super().__init__(eth_provider_uri=self.ETH_PROVIDER_URI,
|
||||
poa=poa,
|
||||
light=light,
|
||||
*args, **kwargs)
|
||||
def __init__(
|
||||
self,
|
||||
test_accounts: int = NUMBER_OF_ETH_TEST_ACCOUNTS,
|
||||
poa: bool = True,
|
||||
light: bool = False,
|
||||
eth_airdrop: bool = False,
|
||||
*args,
|
||||
**kwargs,
|
||||
):
|
||||
EXPECTED_CONFIRMATION_TIME_IN_SECONDS["free"] = 5 # Just some upper-limit
|
||||
super().__init__(
|
||||
endpoint=self.ETH_PROVIDER_URI,
|
||||
poa=poa,
|
||||
light=light,
|
||||
*args,
|
||||
**kwargs,
|
||||
)
|
||||
self.log = Logger("test-blockchain")
|
||||
self.connect()
|
||||
|
||||
|
|
|
@ -25,16 +25,16 @@ TEST_CHARACTER_CONFIG_BASE_PARAMS = dict(
|
|||
|
||||
def assemble(
|
||||
checksum_address: str = None,
|
||||
eth_provider_uri: str = None,
|
||||
eth_endpoint: str = None,
|
||||
test_registry: ContractRegistry = None,
|
||||
known_nodes: List[Ursula] = None,
|
||||
) -> dict:
|
||||
"""Assemble a dictionary of keyword arguments to use when constructing a test configuration."""
|
||||
# Generate runtime config params
|
||||
runtime_params = dict(
|
||||
eth_provider_uri=eth_provider_uri,
|
||||
eth_endpoint=eth_endpoint,
|
||||
registry=test_registry,
|
||||
network_middleware=MockRestMiddleware(eth_provider_uri=eth_provider_uri),
|
||||
network_middleware=MockRestMiddleware(eth_endpoint=eth_endpoint),
|
||||
known_nodes=known_nodes,
|
||||
checksum_address=checksum_address,
|
||||
)
|
||||
|
@ -47,30 +47,26 @@ def assemble(
|
|||
def make_ursula_test_configuration(
|
||||
operator_address: ChecksumAddress,
|
||||
rest_port: int = select_test_port(),
|
||||
pre_payment_provider: str = None,
|
||||
polygon_endpoint: str = None,
|
||||
**assemble_kwargs
|
||||
) -> UrsulaConfiguration:
|
||||
test_params = assemble(**assemble_kwargs)
|
||||
ursula_config = UrsulaConfiguration(
|
||||
**test_params,
|
||||
rest_port=rest_port,
|
||||
pre_payment_provider=pre_payment_provider,
|
||||
pre_payment_network=TEMPORARY_DOMAIN,
|
||||
polygon_endpoint=polygon_endpoint,
|
||||
operator_address=operator_address,
|
||||
policy_registry=test_params["registry"]
|
||||
)
|
||||
return ursula_config
|
||||
|
||||
|
||||
def make_alice_test_configuration(
|
||||
pre_payment_provider: str = None, **assemble_kwargs
|
||||
polygon_endpoint: str = None, **assemble_kwargs
|
||||
) -> AliceConfiguration:
|
||||
test_params = assemble(**assemble_kwargs)
|
||||
config = AliceConfiguration(
|
||||
**test_params,
|
||||
pre_payment_provider=pre_payment_provider,
|
||||
pre_payment_network=TEMPORARY_DOMAIN,
|
||||
policy_registry=test_params["registry"]
|
||||
polygon_endpoint=polygon_endpoint,
|
||||
)
|
||||
return config
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ from pathlib import Path
|
|||
|
||||
import requests
|
||||
from flask import Response
|
||||
from nucypher_core import MetadataRequest, FleetStateChecksum
|
||||
from nucypher_core import FleetStateChecksum, MetadataRequest
|
||||
|
||||
from nucypher.characters.lawful import Ursula
|
||||
from nucypher.network.middleware import NucypherMiddlewareClient, RestMiddleware
|
||||
|
@ -143,7 +143,7 @@ class NodeIsDownMiddleware(MockRestMiddleware):
|
|||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.client = _MiddlewareClientWithConnectionProblems(
|
||||
eth_provider_uri=TEST_ETH_PROVIDER_URI
|
||||
eth_endpoint=TEST_ETH_PROVIDER_URI
|
||||
)
|
||||
|
||||
def node_is_down(self, node):
|
||||
|
|
|
@ -5,48 +5,54 @@ from typing import List
|
|||
from ape.contracts import ContractInstance
|
||||
from eth_utils import to_checksum_address
|
||||
|
||||
from nucypher.blockchain.eth.networks import NetworksInventory
|
||||
from nucypher.blockchain.eth.domains import (
|
||||
DomainInfo,
|
||||
TACoDomain,
|
||||
)
|
||||
from nucypher.blockchain.eth.registry import (
|
||||
RegistryData,
|
||||
RegistrySource,
|
||||
RegistrySourceManager,
|
||||
)
|
||||
from nucypher.config.constants import TEMPORARY_DOMAIN
|
||||
from tests.constants import TESTERCHAIN_CHAIN_INFO
|
||||
|
||||
|
||||
@contextmanager
|
||||
def mock_registry_sources():
|
||||
# capture the real values
|
||||
real_networks = NetworksInventory.NETWORKS
|
||||
real_eth_networks = NetworksInventory.ETH_NETWORKS
|
||||
real_poly_networks = NetworksInventory.POLY_NETWORKS
|
||||
real_registry_sources = RegistrySourceManager._FALLBACK_CHAIN
|
||||
def mock_registry_sources(mocker, domain_names: List[str] = None):
|
||||
if not domain_names:
|
||||
domain_names = [TEMPORARY_DOMAIN]
|
||||
|
||||
# set the mock values
|
||||
RegistrySourceManager._FALLBACK_CHAIN = (MockRegistrySource,)
|
||||
NetworksInventory.NETWORKS = (TEMPORARY_DOMAIN,)
|
||||
NetworksInventory.ETH_NETWORKS = (TEMPORARY_DOMAIN,)
|
||||
NetworksInventory.POLY_NETWORKS = (TEMPORARY_DOMAIN,)
|
||||
supported_domains = []
|
||||
supported_domain_names = []
|
||||
for domain_name in domain_names:
|
||||
test_domain = DomainInfo(
|
||||
domain_name, TESTERCHAIN_CHAIN_INFO, TESTERCHAIN_CHAIN_INFO
|
||||
)
|
||||
supported_domains.append(test_domain)
|
||||
supported_domain_names.append(domain_name)
|
||||
|
||||
mocker.patch.object(TACoDomain, "SUPPORTED_DOMAINS", supported_domains)
|
||||
mocker.patch.object(TACoDomain, "SUPPORTED_DOMAIN_NAMES", supported_domain_names)
|
||||
mocker.patch.object(MockRegistrySource, "ALLOWED_DOMAINS", domain_names)
|
||||
|
||||
mocker.patch.object(RegistrySourceManager, "_FALLBACK_CHAIN", (MockRegistrySource,))
|
||||
|
||||
yield # run the test
|
||||
|
||||
# restore the real values
|
||||
RegistrySourceManager._FALLBACK_CHAIN = real_registry_sources
|
||||
NetworksInventory.NETWORKS = real_networks
|
||||
NetworksInventory.ETH_NETWORKS = real_eth_networks
|
||||
NetworksInventory.POLY_NETWORKS = real_poly_networks
|
||||
|
||||
|
||||
class MockRegistrySource(RegistrySource):
|
||||
ALLOWED_DOMAINS = [TEMPORARY_DOMAIN]
|
||||
|
||||
name = "Mock Registry Source"
|
||||
is_primary = False
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
if self.domain != TEMPORARY_DOMAIN:
|
||||
if self.domain not in self.ALLOWED_DOMAINS:
|
||||
raise ValueError(
|
||||
f"Somehow, MockRegistrySource is trying to get a registry for '{self.domain}'. "
|
||||
f"Only '{TEMPORARY_DOMAIN}' is supported.'"
|
||||
f"Only '{','.join(self.ALLOWED_DOMAINS)}' are supported.'"
|
||||
)
|
||||
|
||||
@property
|
||||
|
|
|
@ -10,7 +10,7 @@ from nucypher.characters.lawful import Ursula
|
|||
from nucypher.config.characters import UrsulaConfiguration
|
||||
from nucypher.policy.conditions.evm import _CONDITION_CHAINS
|
||||
from tests.constants import (
|
||||
NUMBER_OF_URSULAS_IN_DEVELOPMENT_NETWORK,
|
||||
NUMBER_OF_URSULAS_IN_DEVELOPMENT_DOMAIN,
|
||||
TESTERCHAIN_CHAIN_ID,
|
||||
)
|
||||
|
||||
|
@ -68,7 +68,7 @@ def make_ursulas(
|
|||
ursula_config: UrsulaConfiguration,
|
||||
staking_provider_addresses: Iterable[str],
|
||||
operator_addresses: Iterable[str],
|
||||
quantity: int = NUMBER_OF_URSULAS_IN_DEVELOPMENT_NETWORK,
|
||||
quantity: int = NUMBER_OF_URSULAS_IN_DEVELOPMENT_DOMAIN,
|
||||
know_each_other: bool = True,
|
||||
**ursula_overrides
|
||||
) -> List[Ursula]:
|
||||
|
@ -133,13 +133,15 @@ def mock_permitted_multichain_connections(mocker) -> List[int]:
|
|||
def setup_multichain_ursulas(chain_ids: List[int], ursulas: List[Ursula]) -> None:
|
||||
base_uri = "tester://multichain.{}"
|
||||
base_fallback_uri = "tester://multichain.fallback.{}"
|
||||
provider_uris = [base_uri.format(i) for i in range(len(chain_ids))]
|
||||
fallback_provider_uris = [
|
||||
blockchain_endpoints = [base_uri.format(i) for i in range(len(chain_ids))]
|
||||
fallback_blockchain_endpoints = [
|
||||
base_fallback_uri.format(i) for i in range(len(chain_ids))
|
||||
]
|
||||
mocked_condition_providers = {
|
||||
cid: {HTTPProvider(uri), HTTPProvider(furi)}
|
||||
for cid, uri, furi in zip(chain_ids, provider_uris, fallback_provider_uris)
|
||||
for cid, uri, furi in zip(
|
||||
chain_ids, blockchain_endpoints, fallback_blockchain_endpoints
|
||||
)
|
||||
}
|
||||
for ursula in ursulas:
|
||||
ursula.condition_providers = mocked_condition_providers
|
||||
|
|
Loading…
Reference in New Issue