mirror of https://github.com/nucypher/nucypher.git
Support agents with different blockchain connections.
parent
0f82db319e
commit
cdaa6b1358
|
@ -18,7 +18,7 @@ along with nucypher. If not, see <https://www.gnu.org/licenses/>.
|
|||
|
||||
from decimal import Decimal, localcontext
|
||||
from math import log
|
||||
from typing import Tuple
|
||||
from typing import Tuple, Optional
|
||||
|
||||
from nucypher.blockchain.eth.agents import (
|
||||
AdjudicatorAgent,
|
||||
|
@ -448,26 +448,26 @@ class EconomicsFactory:
|
|||
__economics = dict()
|
||||
|
||||
@classmethod
|
||||
def get_economics(cls, registry: BaseContractRegistry) -> BaseEconomics:
|
||||
def get_economics(cls, registry: BaseContractRegistry, provider_uri: Optional[str] = None) -> BaseEconomics:
|
||||
registry_id = registry.id
|
||||
try:
|
||||
return cls.__economics[registry_id]
|
||||
except KeyError:
|
||||
economics = EconomicsFactory.retrieve_from_blockchain(registry=registry)
|
||||
economics = EconomicsFactory.retrieve_from_blockchain(registry=registry, provider_uri=provider_uri)
|
||||
cls.__economics[registry_id] = economics
|
||||
return economics
|
||||
|
||||
@staticmethod
|
||||
def retrieve_from_blockchain(registry: BaseContractRegistry) -> BaseEconomics:
|
||||
def retrieve_from_blockchain(registry: BaseContractRegistry, provider_uri: Optional[str] = None) -> BaseEconomics:
|
||||
|
||||
# Agents
|
||||
token_agent = ContractAgency.get_agent(NucypherTokenAgent, registry=registry)
|
||||
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=registry)
|
||||
adjudicator_agent = ContractAgency.get_agent(AdjudicatorAgent, registry=registry)
|
||||
token_agent = ContractAgency.get_agent(NucypherTokenAgent, registry=registry, provider_uri=provider_uri)
|
||||
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=registry, provider_uri=provider_uri)
|
||||
adjudicator_agent = ContractAgency.get_agent(AdjudicatorAgent, registry=registry, provider_uri=provider_uri)
|
||||
|
||||
worklock_deployed = True
|
||||
try:
|
||||
worklock_agent = ContractAgency.get_agent(WorkLockAgent, registry=registry)
|
||||
worklock_agent = ContractAgency.get_agent(WorkLockAgent, registry=registry, provider_uri=provider_uri)
|
||||
except registry.UnknownContract:
|
||||
worklock_deployed = False
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ class CanonicalRegistrySource(ABC):
|
|||
raise NotImplementedError
|
||||
|
||||
def __repr__(self):
|
||||
return self.get_publication_endpoint()
|
||||
return str(self.get_publication_endpoint())
|
||||
|
||||
|
||||
class GithubRegistrySource(CanonicalRegistrySource):
|
||||
|
|
|
@ -165,17 +165,13 @@ class Character(Learner):
|
|||
# Blockchainy
|
||||
if not self.federated_only:
|
||||
self.provider_uri = provider_uri
|
||||
|
||||
# TODO: Implicit / lazy blockchain connection here?
|
||||
# if not BlockchainInterfaceFactory.is_interface_initialized(provider_uri=provider_uri):
|
||||
# BlockchainInterfaceFactory.initialize_interface(provider_uri=provider_uri)
|
||||
|
||||
self.registry = registry or InMemoryContractRegistry.from_latest_publication(network=domain) # See #1580
|
||||
else:
|
||||
self.registry = NO_BLOCKCHAIN_CONNECTION.bool_value(False)
|
||||
|
||||
# REST
|
||||
self.network_middleware = network_middleware or RestMiddleware(registry=self.registry)
|
||||
self.network_middleware = network_middleware or RestMiddleware(registry=self.registry,
|
||||
provider_uri=provider_uri)
|
||||
|
||||
# Learner
|
||||
Learner.__init__(self,
|
||||
|
|
|
@ -61,6 +61,7 @@ from web3.types import TxReceipt
|
|||
import nucypher
|
||||
from nucypher.acumen.nicknames import Nickname
|
||||
from nucypher.acumen.perception import ArchivedFleetState, RemoteUrsulaStatus
|
||||
from nucypher.blockchain.economics import EconomicsFactory
|
||||
from nucypher.blockchain.eth.actors import ThresholdWorker
|
||||
from nucypher.blockchain.eth.agents import ContractAgency
|
||||
from nucypher.blockchain.eth.agents import StakingEscrowAgent
|
||||
|
@ -92,7 +93,7 @@ from nucypher.network.retrieval import RetrievalClient
|
|||
from nucypher.network.server import ProxyRESTServer, make_rest_app
|
||||
from nucypher.network.trackers import AvailabilityTracker
|
||||
from nucypher.policy.kits import PolicyMessageKit
|
||||
from nucypher.policy.payment import ContractPayment, PaymentMethod, FreeReencryptions
|
||||
from nucypher.policy.payment import PaymentMethod, FreeReencryptions
|
||||
from nucypher.policy.policies import Policy, BlockchainPolicy, FederatedPolicy
|
||||
from nucypher.utilities.logging import Logger
|
||||
from nucypher.utilities.networking import validate_worker_ip
|
||||
|
@ -169,7 +170,10 @@ class Alice(Character):
|
|||
self._crypto_power.consume_power_up(self.transacting_power)
|
||||
|
||||
# BlockchainPolicyAuthor was here
|
||||
self.staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=self.registry)
|
||||
self.economics = EconomicsFactory.get_economics(registry=self.registry, provider_uri=provider_uri)
|
||||
self.staking_agent = ContractAgency.get_agent(StakingEscrowAgent,
|
||||
registry=self.registry,
|
||||
provider_uri=provider_uri)
|
||||
|
||||
self.log = Logger(self.__class__.__name__)
|
||||
if is_me:
|
||||
|
|
|
@ -38,8 +38,9 @@ class NucypherMiddlewareClient:
|
|||
library = requests
|
||||
timeout = 1.2
|
||||
|
||||
def __init__(self, registry=None, *args, **kwargs):
|
||||
def __init__(self, registry=None, provider_uri: str = None, *args, **kwargs):
|
||||
self.registry = registry
|
||||
self.provider_uri = provider_uri
|
||||
|
||||
@staticmethod
|
||||
def response_cleaner(response):
|
||||
|
@ -55,7 +56,7 @@ 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)
|
||||
node.verify_node(network_middleware_client=self, registry=self.registry, provider_uri=self.provider_uri)
|
||||
return self.parse_node_or_host_and_port(node_or_sprout, host, port)
|
||||
|
||||
def parse_node_or_host_and_port(self, node, host, port):
|
||||
|
@ -175,8 +176,8 @@ class RestMiddleware:
|
|||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(status=HTTPStatus.FORBIDDEN, *args, **kwargs)
|
||||
|
||||
def __init__(self, registry=None):
|
||||
self.client = self._client_class(registry)
|
||||
def __init__(self, registry=None, provider_uri: str = None):
|
||||
self.client = self._client_class(registry=registry, provider_uri=provider_uri)
|
||||
|
||||
def get_certificate(self, host, port, timeout=3, retry_attempts: int = 3, retry_rate: int = 2,
|
||||
current_attempt: int = 0):
|
||||
|
|
|
@ -1068,16 +1068,16 @@ class Teacher:
|
|||
raise self.UnbondedWorker(f"Worker {self.worker_address} is not bonded")
|
||||
return staker_address == self.checksum_address
|
||||
|
||||
def _staker_is_really_staking(self, registry: BaseContractRegistry) -> bool:
|
||||
def _staker_is_really_staking(self, registry: BaseContractRegistry, provider_uri: Optional[str] = None) -> bool:
|
||||
"""
|
||||
This method assumes the stamp's signature is valid and accurate.
|
||||
As a follow-up, this checks that the staker is, indeed, staking.
|
||||
"""
|
||||
# Lazy agent get or create
|
||||
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=registry) # type: StakingEscrowAgent
|
||||
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=registry, provider_uri=provider_uri) # type: StakingEscrowAgent
|
||||
|
||||
try:
|
||||
economics = EconomicsFactory.get_economics(registry=registry)
|
||||
economics = EconomicsFactory.get_economics(registry=registry, provider_uri=provider_uri)
|
||||
except Exception:
|
||||
raise # TODO: Get StandardEconomics NRN
|
||||
|
||||
|
@ -1088,7 +1088,7 @@ class Teacher:
|
|||
is_staking = max(stake_current_period, stake_next_period) >= min_stake
|
||||
return is_staking
|
||||
|
||||
def validate_worker(self, registry: BaseContractRegistry = None) -> None:
|
||||
def validate_worker(self, registry: BaseContractRegistry = None, provider_uri: Optional[str] = None) -> None:
|
||||
|
||||
# Federated
|
||||
if self.federated_only:
|
||||
|
@ -1113,7 +1113,7 @@ class Teacher:
|
|||
self.log.debug(message)
|
||||
raise self.UnbondedWorker(message)
|
||||
|
||||
if self._staker_is_really_staking(registry=registry): # <-- Blockchain CALL
|
||||
if self._staker_is_really_staking(registry=registry, provider_uri=provider_uri): # <-- Blockchain CALL
|
||||
self.verified_worker = True
|
||||
else:
|
||||
raise self.NotStaking(f"Staker {self.checksum_address} is not staking")
|
||||
|
@ -1131,7 +1131,7 @@ class Teacher:
|
|||
else:
|
||||
raise self.InvalidNode("Metadata signature is invalid")
|
||||
|
||||
def validate_metadata(self, registry: BaseContractRegistry = None):
|
||||
def validate_metadata(self, registry: BaseContractRegistry = None, provider_uri: Optional[str] = None):
|
||||
|
||||
# Verify the metadata signature
|
||||
if not self.verified_metadata:
|
||||
|
@ -1143,7 +1143,7 @@ class Teacher:
|
|||
|
||||
# Offline check of valid stamp signature by worker
|
||||
try:
|
||||
self.validate_worker(registry=registry)
|
||||
self.validate_worker(registry=registry, provider_uri=provider_uri)
|
||||
except self.WrongMode:
|
||||
if bool(registry):
|
||||
raise
|
||||
|
@ -1151,6 +1151,7 @@ class Teacher:
|
|||
def verify_node(self,
|
||||
network_middleware_client,
|
||||
registry: BaseContractRegistry = None,
|
||||
provider_uri: Optional[str] = None,
|
||||
certificate_filepath: Optional[Path] = None,
|
||||
force: bool = False
|
||||
) -> bool:
|
||||
|
@ -1182,7 +1183,7 @@ class Teacher:
|
|||
"on-chain Staking verification will not be performed.")
|
||||
|
||||
# This is both the stamp's client signature and interface metadata check; May raise InvalidNode
|
||||
self.validate_metadata(registry=registry)
|
||||
self.validate_metadata(registry=registry, provider_uri=provider_uri)
|
||||
|
||||
# The node's metadata is valid; let's be sure the interface is in order.
|
||||
if not certificate_filepath:
|
||||
|
|
|
@ -81,7 +81,6 @@ class ContractPayment(PaymentMethod, ABC):
|
|||
self.provider = provider
|
||||
self.network = network
|
||||
self.registry = InMemoryContractRegistry.from_latest_publication(network=network)
|
||||
self.economics = EconomicsFactory.get_economics(registry=self.registry)
|
||||
self.__agent = None # delay blockchain/registry reads until later
|
||||
|
||||
@property
|
||||
|
@ -134,6 +133,10 @@ class PolicyManagerPayment(ContractPayment):
|
|||
|
||||
_AGENT = PolicyManagerAgent
|
||||
NAME = 'PolicyManager'
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.economics = EconomicsFactory.get_economics(registry=self.registry, provider_uri=self.provider)
|
||||
|
||||
def verify(self, payee: ChecksumAddress, request: ReencryptionRequest) -> bool:
|
||||
"""Verify policy payment by reading the PolicyManager contract"""
|
||||
|
|
Loading…
Reference in New Issue