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.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,
@ -69,7 +70,7 @@ class BaseActor:
@validate_checksum_address
def __init__(
self,
domain: str,
domain: TACoDomain,
registry: ContractRegistry,
transacting_power: Optional[TransactingPower] = None,
checksum_address: Optional[ChecksumAddress] = None,
@ -92,7 +93,7 @@ class BaseActor:
self.transacting_power = transacting_power
self.registry = registry
self.domain = domains.get_domain(str(domain))
self.domain = domain
self._saved_receipts = list() # track receipts of transmitted transactions
def __repr__(self):

View File

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

View File

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

View File

@ -79,6 +79,8 @@ class Character(Learner):
"""
self.domain = domains.get_domain(str(domain))
#
# Keys & Powers
#
@ -118,9 +120,7 @@ class Character(Learner):
self.eth_endpoint = eth_endpoint
self.polygon_endpoint = polygon_endpoint
self.registry = registry or ContractRegistry.from_latest_publication(
domain=domains.get_domain(str(domain)),
)
self.registry = registry or ContractRegistry.from_latest_publication(domain)
# REST
self.network_middleware = network_middleware or RestMiddleware(
@ -129,7 +129,6 @@ class Character(Learner):
# Learner
Learner.__init__(self,
domain=domain,
network_middleware=self.network_middleware,
node_class=known_node_class,
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,
**character_kwargs,
):
domain = domains.get_domain(str(domain))
Character.__init__(
self,
is_me=is_me,
@ -905,7 +904,6 @@ class Ursula(Teacher, Character, Operator):
# Teacher (All Modes)
Teacher.__init__(
self,
domain=domain,
certificate=certificate,
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.agents import ContractAgency, TACoApplicationAgent
from nucypher.blockchain.eth.constants import NULL_ADDRESS
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
@ -251,7 +252,6 @@ class Learner:
"""
def __init__(self,
domain: str,
node_class: object = None,
network_middleware: RestMiddleware = None,
start_learning_now: bool = False,
@ -269,7 +269,6 @@ class Learner:
self.log = Logger("learning-loop") # type: Logger
self.learning_deferred = Deferred()
self.domain = domains.get_domain(str(domain))
default_middleware = self.__DEFAULT_MIDDLEWARE_CLASS(
registry=self.registry, eth_endpoint=self.eth_endpoint
)
@ -280,7 +279,7 @@ class Learner:
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.lonely = lonely
@ -969,13 +968,10 @@ class Teacher:
__DEFAULT_MIN_SEED_STAKE = 0
def __init__(self,
domain: str, # TODO: Consider using a Domain type
certificate: Certificate,
certificate_filepath: Path,
) -> None:
self.domain = domain
#
# Identity
#

View File

@ -73,7 +73,7 @@ class ContractPayment(PaymentMethod, ABC):
):
super().__init__(*args, **kwargs)
self.blockchain_endpoint = blockchain_endpoint
self.domain = domains.get_domain(str(domain))
self.domain = domain
if not registry:
registry = ContractRegistry.from_latest_publication(domain=self.domain)
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.signing import InvalidSignature
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
@ -21,7 +21,7 @@ def test_actor_without_signing_power_cannot_sign():
non_signer = Character(
crypto_power=cannot_sign,
start_learning_now=False,
domain=TEMPORARY_DOMAIN_NAME,
domain=TEMPORARY_DOMAIN,
eth_endpoint=MOCK_ETH_PROVIDER_URI,
)
@ -46,7 +46,7 @@ def test_actor_with_signing_power_can_sign():
crypto_power_ups=[SigningPower],
is_me=True,
start_learning_now=False,
domain=TEMPORARY_DOMAIN_NAME,
domain=TEMPORARY_DOMAIN,
eth_endpoint=MOCK_ETH_PROVIDER_URI,
)
stamp_of_the_signer = signer.stamp