Bug fixes indicated by mypy checks; More annotations for all.

pull/444/head
Kieran Prasch 2018-09-21 11:42:44 -07:00
parent 824ef32a85
commit 37c3ffd384
7 changed files with 67 additions and 48 deletions

View File

@ -42,13 +42,13 @@ class NucypherTokenActor:
if parent_address != checksum_address:
raise ValueError("Can't have two different addresses.")
except AttributeError:
self.checksum_public_address = checksum_address
self.checksum_public_address = checksum_address # type: str
if registry_filepath is not None:
EthereumContractRegistry(registry_filepath=registry_filepath)
self.token_agent = token_agent if token_agent is not None else NucypherTokenAgent()
self._transaction_cache = list() # track transactions transmitted
self._transaction_cache = list() # type: list # track transactions transmitted
def __repr__(self):
class_name = self.__class__.__name__

View File

@ -98,7 +98,7 @@ class MinerAgent(EthereumContractAgent):
principal_contract_name = "MinersEscrow"
_upgradeable = True
__instance = None
__instance = None # TODO: constants.NO_CONTRACT_AVAILABLE
class NotEnoughMiners(Exception):
pass
@ -110,7 +110,11 @@ class MinerAgent(EthereumContractAgent):
) -> None:
token_agent = token_agent if token_agent is not None else NucypherTokenAgent(registry_filepath=registry_filepath)
super().__init__(blockchain=token_agent.blockchain, registry_filepath=registry_filepath, *args, **kwargs)
super().__init__(blockchain=token_agent.blockchain,
registry_filepath=registry_filepath,
*args, **kwargs)
self.token_agent = token_agent
#

View File

@ -1,9 +1,13 @@
from constant_sorrow import constants
from typing import Tuple, Dict
from constant_sorrow import constants
from nucypher.blockchain.eth.agents import EthereumContractAgent, MinerAgent, NucypherTokenAgent, PolicyAgent, \
from nucypher.blockchain.eth.agents import (
EthereumContractAgent,
MinerAgent,
NucypherTokenAgent,
PolicyAgent,
UserEscrowAgent
)
from nucypher.blockchain.eth.interfaces import BlockchainDeployerInterface
from .chains import Blockchain
@ -18,10 +22,14 @@ class ContractDeployer:
class ContractDeploymentError(Exception):
pass
def __init__(self, blockchain: Blockchain, deployer_address: str) -> None:
def __init__(self,
blockchain: Blockchain,
deployer_address: str
) -> None:
self.__armed = False
self._contract = None
self.deployment_receipt = None
self._contract = constants.CONTRACT_NOT_DEPLOYED
self.deployment_receipt = constants.CONTRACT_NOT_DEPLOYED
self.__dispatcher = NotImplemented
# Sanity check
@ -33,13 +41,11 @@ class ContractDeployer:
@property
def contract_address(self) -> str:
try:
address = self._contract.address
except AttributeError:
if self._contract is constants.CONTRACT_NOT_DEPLOYED:
cls = self.__class__
raise cls.ContractDeploymentError('Contract not deployed')
else:
return address
raise ContractDeployer.ContractDeploymentError('Contract not deployed')
address = self._contract.address # type: str
return address
@property
def deployer_address(self):
@ -55,7 +61,7 @@ class ContractDeployer:
@property
def is_deployed(self) -> bool:
return bool(self._contract is not None)
return bool(self._contract is not constants.CONTRACT_NOT_DEPLOYED)
@property
def is_armed(self) -> bool:
@ -95,14 +101,14 @@ class ContractDeployer:
def _ensure_contract_deployment(self) -> bool:
"""Raises ContractDeploymentError if the contract has not been armed and deployed."""
if self._contract is None:
if self._contract is constants.CONTRACT_NOT_DEPLOYED:
class_name = self.__class__.__name__
message = '{} contract is not deployed. Arm, then deploy.'.format(class_name)
raise self.ContractDeploymentError(message)
return True
def arm(self, fail_on_abort=True) -> None:
def arm(self, fail_on_abort: bool = True) -> None:
"""
Safety mechanism for ethereum contract deployment
@ -140,7 +146,7 @@ class ContractDeployer:
arm = True # If this is a private chain, just arm the deployer without interaction.
self.__armed = arm # Set the arming status
def deploy(self) -> str:
def deploy(self) -> dict:
"""
Used after arming the deployer;
Provides for the setup, deployment, and initialization of ethereum smart contracts.
@ -158,7 +164,11 @@ class NucypherTokenDeployer(ContractDeployer):
agency = NucypherTokenAgent
_contract_name = agency.principal_contract_name # TODO
def __init__(self, blockchain, deployer_address) -> None:
def __init__(self,
blockchain,
deployer_address: str
) -> None:
if not type(blockchain.interface) is self._interface_class:
raise ValueError("{} must be used to create a {}".format(self._interface_class.__name__,
self.__class__.__name__))
@ -166,7 +176,7 @@ class NucypherTokenDeployer(ContractDeployer):
super().__init__(blockchain=blockchain, deployer_address=deployer_address)
self._creator = deployer_address
def deploy(self) -> str:
def deploy(self) -> dict:
"""
Deploy and publish the NuCypher Token contract
to the blockchain network specified in self.blockchain.network.
@ -183,7 +193,7 @@ class NucypherTokenDeployer(ContractDeployer):
int(constants.TOKEN_SATURATION))
self._contract = _contract
return self.deployment_receipt
return {'deployment_receipt': self.deployment_receipt}
class DispatcherDeployer(ContractDeployer):
@ -199,14 +209,14 @@ class DispatcherDeployer(ContractDeployer):
self.secret_hash = secret_hash
super().__init__(*args, **kwargs)
def deploy(self) -> str:
def deploy(self) -> dict:
dispatcher_contract, txhash = self.blockchain.interface.deploy_contract('Dispatcher',
self.target_contract.address,
self.secret_hash)
self._contract = dispatcher_contract
return txhash
return {'txhash': txhash}
class MinerEscrowDeployer(ContractDeployer):
@ -227,7 +237,7 @@ class MinerEscrowDeployer(ContractDeployer):
if result is constants.NULL_ADDRESS:
raise RuntimeError("PolicyManager contract is not initialized.")
def deploy(self) -> Dict[str, str]:
def deploy(self) -> dict:
"""
Deploy and publish the NuCypher Token contract
to the blockchain network specified in self.blockchain.network.
@ -383,7 +393,7 @@ class UserEscrowDeployer(ContractDeployer):
self.token_deployer = miner_escrow_deployer.token_deployer
super().__init__(blockchain=miner_escrow_deployer.blockchain, *args, **kwargs)
def deploy(self):
def deploy(self) -> dict:
is_ready, _disqualifications = self.check_ready_to_deploy(fail=True)
assert is_ready
@ -391,11 +401,11 @@ class UserEscrowDeployer(ContractDeployer):
self.miner_deployer.contract_address,
self.policy_deployer.contract_address]
deploy_transaction = {'from': self.token_deployer.contract_address}
deploy_transaction = {'from': self.token_deployer.contract_address} # TODO:.. eh?
the_user_escrow_contract, deploy_txhash = self.blockchain.interface.deploy_contract(
self._contract_name,
*deployment_args)
self._contract = the_user_escrow_contract
return deploy_txhash
return {'deploy_txhash': deploy_txhash}

View File

@ -171,7 +171,7 @@ class BlockchainInterface:
return circumflex
@property
def providers(self) -> Tuple[Union[IPCProvider, WebsocketProvider, HTTPProvider]]:
def providers(self) -> Tuple[Union[IPCProvider, WebsocketProvider, HTTPProvider], ...]:
return tuple(self.__providers)
@property

View File

@ -1,5 +1,5 @@
from collections import deque
from typing import List, Tuple
from typing import List, Tuple, Iterable
from typing import Set
import math
@ -9,7 +9,7 @@ from eth_utils import to_canonical_address
from nucypher.blockchain.eth.actors import Miner
from nucypher.blockchain.eth.actors import PolicyAuthor
from nucypher.blockchain.eth.agents import MinerAgent
from nucypher.blockchain.eth.agents import MinerAgent, PolicyAgent
from nucypher.blockchain.eth.constants import calculate_period_duration
from nucypher.characters.lawful import Ursula
from nucypher.network.middleware import RestMiddleware
@ -36,22 +36,22 @@ class BlockchainArrangement(Arrangement):
periods = int(math.ceil(hours / int(constants.HOURS_PER_PERIOD))) # type: int
# The relationship exists between two addresses
self.author = author
self.policy_agent = author.policy_agent
self.author = author # type: PolicyAuthor
self.policy_agent = author.policy_agent # type: PolicyAgent
self.miner = miner
self.miner = miner # type: Miner
# Arrangement value, rate, and duration
rate = value // lock_periods
self._rate = rate
rate = value // lock_periods # type: int
self._rate = rate # type: int
self.value = value
self.lock_periods = lock_periods # TODO: <datetime> -> lock_periods
self.value = value # type: int
self.lock_periods = lock_periods # type: int # TODO: <datetime> -> lock_periods
self.is_published = False
self.is_published = False # type: bool
self.publish_transaction = None
self.is_revoked = False
self.is_revoked = False # type: bool
self.revoke_transaction = None
def __repr__(self):
@ -61,9 +61,11 @@ class BlockchainArrangement(Arrangement):
return r
def publish(self) -> str:
payload = {'from': self.author._ether_address, 'value': self.value}
payload = {'from': self.author.checksum_public_address,
'value': self.value}
txhash = self.policy_agent.contract.functions.createPolicy(self.id, self.miner._ether_address,
txhash = self.policy_agent.contract.functions.createPolicy(self.id,
self.miner.checksum_public_address,
self.lock_periods).transact(payload)
self.policy_agent.blockchain.wait_for_receipt(txhash)

View File

@ -2,7 +2,7 @@ import binascii
import uuid
from abc import abstractmethod
from collections import OrderedDict
from typing import Generator, List, Set
from typing import Generator, List, Set, Iterable
import maya
import msgpack
@ -259,7 +259,7 @@ class Policy:
network_middleware: RestMiddleware,
deposit: int,
expiration: maya.MayaDT,
ursulas: List[Ursula] = None) -> None:
ursulas: Set[Ursula] = None) -> None:
"""
Create and consider n Arangement objects.
"""

View File

@ -4,6 +4,7 @@ from typing import List
import maya
from nucypher.characters.lawful import Ursula
from nucypher.network.middleware import RestMiddleware
from nucypher.policy.models import Arrangement, Policy
@ -18,15 +19,17 @@ class MockArrangement(Arrangement):
class MockPolicy(Policy):
def make_arrangements(self, network_middleware,
def make_arrangements(self,
network_middleware: RestMiddleware,
deposit: int,
expiration: maya.MayaDT,
ursulas: List[Ursula] = None) -> None:
ursulas: Set[Ursula] = None
) -> None:
"""
Create and consider n Arangement objects from all known nodes.
"""
for ursula in self.alice._known_nodes:
for ursula in self.alice.known_nodes:
arrangement = MockArrangement(alice=self.alice, ursula=ursula,
hrac=self.hrac(),
expiration=expiration)