use domain lookups sparingly and cache the lookups results

pull/3322/head
Kieran Prasch 2023-10-29 20:15:52 +01:00 committed by KPrasch
parent ae9f4b40fa
commit de8d96e8ea
8 changed files with 18 additions and 32 deletions

View File

@ -37,6 +37,7 @@ from nucypher.blockchain.eth.agents import (
from nucypher.blockchain.eth.clients import PUBLIC_CHAINS from nucypher.blockchain.eth.clients import PUBLIC_CHAINS
from nucypher.blockchain.eth.constants import NULL_ADDRESS from nucypher.blockchain.eth.constants import NULL_ADDRESS
from nucypher.blockchain.eth.decorators import validate_checksum_address from nucypher.blockchain.eth.decorators import validate_checksum_address
from nucypher.blockchain.eth.domains import TACoDomain
from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory
from nucypher.blockchain.eth.registry import ( from nucypher.blockchain.eth.registry import (
ContractRegistry, ContractRegistry,
@ -69,7 +70,7 @@ class BaseActor:
@validate_checksum_address @validate_checksum_address
def __init__( def __init__(
self, self,
domain: str, domain: TACoDomain,
registry: ContractRegistry, registry: ContractRegistry,
transacting_power: Optional[TransactingPower] = None, transacting_power: Optional[TransactingPower] = None,
checksum_address: Optional[ChecksumAddress] = None, checksum_address: Optional[ChecksumAddress] = None,
@ -92,7 +93,7 @@ class BaseActor:
self.transacting_power = transacting_power self.transacting_power = transacting_power
self.registry = registry self.registry = registry
self.domain = domains.get_domain(str(domain)) self.domain = domain
self._saved_receipts = list() # track receipts of transmitted transactions self._saved_receipts = list() # track receipts of transmitted transactions
def __repr__(self): def __repr__(self):

View File

@ -1,3 +1,4 @@
from cytoolz.functoolz import memoize
from enum import Enum from enum import Enum
from typing import NamedTuple, Dict from typing import NamedTuple, Dict
@ -24,11 +25,7 @@ class PolygonChain(ChainInfo, Enum):
class TACoDomain: class TACoDomain:
def __init__(self, def __init__(self, name: str, eth_chain: EthChain, polygon_chain: PolygonChain):
name: str,
eth_chain: EthChain,
polygon_chain: PolygonChain,
):
self.name = name self.name = name
self.eth_chain = eth_chain self.eth_chain = eth_chain
self.polygon_chain = polygon_chain self.polygon_chain = polygon_chain
@ -54,9 +51,6 @@ class TACoDomain:
def __bool__(self): def __bool__(self):
return True return True
def __iter__(self):
return str(self)
@property @property
def is_testnet(self) -> bool: def is_testnet(self) -> bool:
return self.eth_chain != EthChain.MAINNET return self.eth_chain != EthChain.MAINNET
@ -80,14 +74,14 @@ TAPIR = TACoDomain(
polygon_chain=PolygonChain.MUMBAI, polygon_chain=PolygonChain.MUMBAI,
) )
__DOMAINS = (MAINNET, LYNX, TAPIR)
DEFAULT_DOMAIN: TACoDomain = MAINNET DEFAULT_DOMAIN: TACoDomain = MAINNET
SUPPORTED_DOMAINS: Dict[str, TACoDomain] = {domain.name: domain for domain in __DOMAINS} SUPPORTED_DOMAINS: Dict[str, TACoDomain] = {domain.name: domain for domain in (MAINNET, LYNX, TAPIR)}
@memoize
def get_domain(d: str) -> TACoDomain: def get_domain(d: str) -> TACoDomain:
if not isinstance(d, str): if not isinstance(d, str):
raise TypeError(f"domain must be a string, not {type(d)}") raise TypeError(f"domain must be a string, not {type(d)}")

View File

@ -34,8 +34,7 @@ class RegistrySource(ABC):
class Unavailable(RegistrySourceError): class Unavailable(RegistrySourceError):
"""Raised when there are no available registry sources""" """Raised when there are no available registry sources"""
def __init__(self, domain: Union[str, TACoDomain], *args, **kwargs): def __init__(self, domain: TACoDomain, *args, **kwargs):
domain = domains.get_domain(str(domain))
if str(domain) not in domains.SUPPORTED_DOMAINS: if str(domain) not in domains.SUPPORTED_DOMAINS:
raise ValueError( raise ValueError(
f"{self.__class__.__name__} not available for domain '{domain}'. " f"{self.__class__.__name__} not available for domain '{domain}'. "
@ -303,11 +302,10 @@ class ContractRegistry:
@classmethod @classmethod
def from_latest_publication( def from_latest_publication(
cls, cls,
domain: Union[str, TACoDomain], domain: TACoDomain,
source_manager: Optional[RegistrySourceManager] = None, source_manager: Optional[RegistrySourceManager] = None,
) -> "ContractRegistry": ) -> "ContractRegistry":
"""Get the latest contract registry available from a registry source chain.""" """Get the latest contract registry available from a registry source chain."""
domain = domains.get_domain(str(domain))
source_manager = source_manager or RegistrySourceManager(domain=domain) source_manager = source_manager or RegistrySourceManager(domain=domain)
source = source_manager.fetch_latest_publication() source = source_manager.fetch_latest_publication()
registry = cls(source=source) registry = cls(source=source)

View File

@ -79,6 +79,8 @@ class Character(Learner):
""" """
self.domain = domains.get_domain(str(domain))
# #
# Keys & Powers # Keys & Powers
# #
@ -118,9 +120,7 @@ class Character(Learner):
self.eth_endpoint = eth_endpoint self.eth_endpoint = eth_endpoint
self.polygon_endpoint = polygon_endpoint self.polygon_endpoint = polygon_endpoint
self.registry = registry or ContractRegistry.from_latest_publication( self.registry = registry or ContractRegistry.from_latest_publication(domain)
domain=domains.get_domain(str(domain)),
)
# REST # REST
self.network_middleware = network_middleware or RestMiddleware( self.network_middleware = network_middleware or RestMiddleware(
@ -129,7 +129,6 @@ class Character(Learner):
# Learner # Learner
Learner.__init__(self, Learner.__init__(self,
domain=domain,
network_middleware=self.network_middleware, network_middleware=self.network_middleware,
node_class=known_node_class, node_class=known_node_class,
include_self_in_the_state=include_self_in_the_state, include_self_in_the_state=include_self_in_the_state,

View File

@ -827,7 +827,6 @@ class Ursula(Teacher, Character, Operator):
known_nodes: Iterable[Teacher] = None, known_nodes: Iterable[Teacher] = None,
**character_kwargs, **character_kwargs,
): ):
domain = domains.get_domain(str(domain))
Character.__init__( Character.__init__(
self, self,
is_me=is_me, is_me=is_me,
@ -905,7 +904,6 @@ class Ursula(Teacher, Character, Operator):
# Teacher (All Modes) # Teacher (All Modes)
Teacher.__init__( Teacher.__init__(
self, self,
domain=domain,
certificate=certificate, certificate=certificate,
certificate_filepath=certificate_filepath, certificate_filepath=certificate_filepath,
) )

View File

@ -29,6 +29,7 @@ from nucypher.acumen.perception import FleetSensor
from nucypher.blockchain.eth import domains from nucypher.blockchain.eth import domains
from nucypher.blockchain.eth.agents import ContractAgency, TACoApplicationAgent from nucypher.blockchain.eth.agents import ContractAgency, TACoApplicationAgent
from nucypher.blockchain.eth.constants import NULL_ADDRESS from nucypher.blockchain.eth.constants import NULL_ADDRESS
from nucypher.blockchain.eth.domains import TACoDomain
from nucypher.blockchain.eth.registry import ContractRegistry from nucypher.blockchain.eth.registry import ContractRegistry
from nucypher.config.constants import SeednodeMetadata from nucypher.config.constants import SeednodeMetadata
from nucypher.config.storages import ForgetfulNodeStorage from nucypher.config.storages import ForgetfulNodeStorage
@ -251,7 +252,6 @@ class Learner:
""" """
def __init__(self, def __init__(self,
domain: str,
node_class: object = None, node_class: object = None,
network_middleware: RestMiddleware = None, network_middleware: RestMiddleware = None,
start_learning_now: bool = False, start_learning_now: bool = False,
@ -269,7 +269,6 @@ class Learner:
self.log = Logger("learning-loop") # type: Logger self.log = Logger("learning-loop") # type: Logger
self.learning_deferred = Deferred() self.learning_deferred = Deferred()
self.domain = domains.get_domain(str(domain))
default_middleware = self.__DEFAULT_MIDDLEWARE_CLASS( default_middleware = self.__DEFAULT_MIDDLEWARE_CLASS(
registry=self.registry, eth_endpoint=self.eth_endpoint registry=self.registry, eth_endpoint=self.eth_endpoint
) )
@ -280,7 +279,7 @@ class Learner:
self._abort_on_learning_error = abort_on_learning_error self._abort_on_learning_error = abort_on_learning_error
self.__known_nodes = self.tracker_class(domain=domain, this_node=self if include_self_in_the_state else None) self.__known_nodes = self.tracker_class(domain=self.domain, this_node=self if include_self_in_the_state else None)
self._verify_node_bonding = verify_node_bonding self._verify_node_bonding = verify_node_bonding
self.lonely = lonely self.lonely = lonely
@ -969,13 +968,10 @@ class Teacher:
__DEFAULT_MIN_SEED_STAKE = 0 __DEFAULT_MIN_SEED_STAKE = 0
def __init__(self, def __init__(self,
domain: str, # TODO: Consider using a Domain type
certificate: Certificate, certificate: Certificate,
certificate_filepath: Path, certificate_filepath: Path,
) -> None: ) -> None:
self.domain = domain
# #
# Identity # Identity
# #

View File

@ -73,7 +73,7 @@ class ContractPayment(PaymentMethod, ABC):
): ):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.blockchain_endpoint = blockchain_endpoint self.blockchain_endpoint = blockchain_endpoint
self.domain = domains.get_domain(str(domain)) self.domain = domain
if not registry: if not registry:
registry = ContractRegistry.from_latest_publication(domain=self.domain) registry = ContractRegistry.from_latest_publication(domain=self.domain)
self.registry = registry self.registry = registry

View File

@ -5,7 +5,7 @@ from nucypher.config.constants import TEMPORARY_DOMAIN_NAME
from nucypher.crypto.powers import CryptoPower, NoSigningPower, SigningPower from nucypher.crypto.powers import CryptoPower, NoSigningPower, SigningPower
from nucypher.crypto.signing import InvalidSignature from nucypher.crypto.signing import InvalidSignature
from nucypher.policy.payment import FreeReencryptions from nucypher.policy.payment import FreeReencryptions
from tests.constants import MOCK_ETH_PROVIDER_URI from tests.constants import MOCK_ETH_PROVIDER_URI, TEMPORARY_DOMAIN
""" """
Chapter 1: SIGNING Chapter 1: SIGNING
@ -21,7 +21,7 @@ def test_actor_without_signing_power_cannot_sign():
non_signer = Character( non_signer = Character(
crypto_power=cannot_sign, crypto_power=cannot_sign,
start_learning_now=False, start_learning_now=False,
domain=TEMPORARY_DOMAIN_NAME, domain=TEMPORARY_DOMAIN,
eth_endpoint=MOCK_ETH_PROVIDER_URI, eth_endpoint=MOCK_ETH_PROVIDER_URI,
) )
@ -46,7 +46,7 @@ def test_actor_with_signing_power_can_sign():
crypto_power_ups=[SigningPower], crypto_power_ups=[SigningPower],
is_me=True, is_me=True,
start_learning_now=False, start_learning_now=False,
domain=TEMPORARY_DOMAIN_NAME, domain=TEMPORARY_DOMAIN,
eth_endpoint=MOCK_ETH_PROVIDER_URI, eth_endpoint=MOCK_ETH_PROVIDER_URI,
) )
stamp_of_the_signer = signer.stamp stamp_of_the_signer = signer.stamp