[KMS-ETH]- Renames .call to .read, go concrete: Removes ABC for contract wrapper types.

pull/195/head^2
Kieran Prasch 2018-04-06 17:04:31 -07:00
parent 2ea28b4c69
commit 0afe92b9a4
5 changed files with 54 additions and 64 deletions

View File

@ -200,34 +200,34 @@ class Miner(TokenActor):
return staking_transactions return staking_transactions
# TODO: Sidechain datastore def publish_data(self, data) -> str:
# def publish_data(self, miner_id) -> str: """Store new data"""
# """Store a new Miner ID"""
# txhash = self.miner_agent.transact({'from': self.address}).setMinerId(data)
# txhash = self.miner_agent.transact({'from': self.address}).setMinerId(miner_id) self.blockchain.wait_for_receipt(txhash)
# self._blockchain.wait_for_receipt(txhash)
# self._transactions[datetime.utcnow()] = txhash self._transactions[datetime.utcnow()] = txhash
#
# return txhash return txhash
#
# def fetch_miner_data(self) -> tuple: def fetch_data(self) -> tuple:
# """Retrieve all stored Miner IDs on this miner""" """Retrieve all stored Miner IDs on this miner"""
#
# count = self.miner_agent.read().getMinerInfo(self.miner_agent._deployer.MinerInfoField.MINER_IDS_LENGTH.value, count_bytes = self.miner_agent.read().getMinerInfo(self.miner_agent._deployer.MinerInfoField.MINER_IDS_LENGTH.value,
# self.address, self.address,
# 0).encode('latin-1') 0).encode('latin-1') # TODO change when v4 of web3.py is released
#
# count = self._blockchain._chain.web3.toInt(count) count = self.blockchain._chain.web3.toInt(count_bytes)
#
# miner_ids = list() miner_ids = list()
# for index in range(count): for index in range(count):
# miner_id = self.miner_agent.read().getMinerInfo(self.miner_agent._deployer.MinerInfoField.MINER_ID.value, miner_id = self.miner_agent.read().getMinerInfo(self.miner_agent._deployer.MinerInfoField.MINER_ID.value,
# self.address, self.address,
# index) index)
# encoded_miner_id = miner_id.encode('latin-1') # TODO change when v4 of web3.py is released encoded_miner_id = miner_id.encode('latin-1')
# miner_ids.append(encoded_miner_id) miner_ids.append(encoded_miner_id)
#
# return tuple(miner_ids) return tuple(miner_ids)
class PolicyAuthor(TokenActor): class PolicyAuthor(TokenActor):
@ -239,40 +239,12 @@ class PolicyAuthor(TokenActor):
self._arrangements = OrderedDict() # Track authored policies by id self._arrangements = OrderedDict() # Track authored policies by id
def make_arrangement(self, miner: Miner, periods: int, rate: int, arrangement_id: bytes=None) -> 'BlockchainArrangement':
"""
Create a new arrangement to carry out a blockchain policy for the specified rate and time.
"""
value = rate * periods
arrangement = BlockchainArrangement(author=self,
miner=miner,
value=value,
periods=periods)
self._arrangements[arrangement.id] = {arrangement_id: arrangement}
return arrangement
def get_arrangement(self, arrangement_id: bytes) -> BlockchainArrangement:
"""Fetch a published arrangement from the blockchain"""
blockchain_record = self.policy_agent.read().policies(arrangement_id)
author_address, miner_address, rate, start_block, end_block, downtime_index = blockchain_record
duration = end_block - start_block
miner = Miner(address=miner_address, miner_agent=self.policy_agent.miner_agent)
arrangement = BlockchainArrangement(author=self, miner=miner, periods=duration)
arrangement.is_published = True
return arrangement
def revoke_arrangement(self, arrangement_id): def revoke_arrangement(self, arrangement_id):
"""Get the arrangement from the cache and revoke it on the blockchain""" """Get the arrangement from the cache and revoke it on the blockchain"""
try: try:
arrangement = self._arrangements[arrangement_id] arrangement = self._arrangements[arrangement_id]
except KeyError: except KeyError:
raise Exception('No such arrangement') #TODO raise self.ActorError('No such arrangement')
else: else:
txhash = arrangement.revoke() txhash = arrangement.revoke()
return txhash return txhash

View File

@ -7,6 +7,10 @@ from nkms_eth.deployers import MinerEscrowDeployer, NuCypherKMSTokenDeployer, Po
class EthereumContractAgent(ABC): class EthereumContractAgent(ABC):
"""
Base class for ethereum contract wrapper types that interact with blockchain contract instances
"""
_principal_contract_name = NotImplemented _principal_contract_name = NotImplemented
class ContractNotDeployed(ContractDeployer.ContractDeploymentError): class ContractNotDeployed(ContractDeployer.ContractDeploymentError):
@ -38,6 +42,16 @@ class EthereumContractAgent(ABC):
return self.blockchain._chain.web3.eth.accounts[0] # TODO: make swappable return self.blockchain._chain.web3.eth.accounts[0] # TODO: make swappable
def read(self): def read(self):
"""
Returns an object that exposes the contract instance functions.
This method is intended for use with method chaining,
results in zero state changes, and costs zero gas.
Useful as a dry-run before sending an actual transaction.
See more on interacting with contract instances in the Populus docs:
http://populus.readthedocs.io/en/latest/dev_cycle.part-07.html#call-an-instance-function
"""
return self._contract.call() return self._contract.call()
def transact(self, payload: dict): def transact(self, payload: dict):

View File

@ -78,7 +78,8 @@ class TheBlockchain(ABC):
if timeout is None: if timeout is None:
timeout = self._default_timeout timeout = self._default_timeout
self._chain.wait.for_receipt(txhash, timeout=timeout) result = self._chain.wait.for_receipt(txhash, timeout=timeout)
return result
# class TestRpcBlockchain: # class TestRpcBlockchain:
# #

View File

@ -63,7 +63,6 @@ class NuCypherMinerConfig:
def null_address(self): def null_address(self):
return self._null_addr return self._null_addr
@property @property
def mining_coefficient(self): def mining_coefficient(self):
return self.__mining_coeff return self.__mining_coeff
@ -74,18 +73,19 @@ class NuCypherMinerConfig:
class PopulusConfig: class PopulusConfig:
__project_name = 'nucypher-kms'
def __init__(self, project_name='nucypher-kms', registrar_path=None): def __init__(self, registrar_path=None):
self._python_project_name = project_name
# This config is persistent and is created in user's .local directory # This config is persistent and is created in user's .local directory
if registrar_path is None: if registrar_path is None:
registrar_path = join(appdirs.user_data_dir(self._python_project_name), 'registrar.json') registrar_path = join(appdirs.user_data_dir(self.__project_name), 'registrar.json')
self._registrar_path = registrar_path self._registrar_path = registrar_path
# Populus project config # Populus project config
self._project_dir = join(dirname(abspath(nkms_eth.__file__)), 'project') self._project_dir = join(dirname(abspath(nkms_eth.__file__)), 'project')
self._populus_project = populus.Project(self._project_dir) self._populus_project = populus.Project(self._project_dir)
self.project.config['chains.mainnetrpc.contracts.backends.JSONFile.settings.file_path'] = self._registrar_path self.project.config['chains.mainnetrpc.contracts.backends.JSONFile.settings.file_path'] = self._registrar_path
@property @property

View File

@ -1,13 +1,16 @@
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from typing import Tuple from typing import Tuple, Dict
from populus.contracts.contract import PopulusContract
from nkms_eth.config import NuCypherMinerConfig, NuCypherTokenConfig from nkms_eth.config import NuCypherMinerConfig, NuCypherTokenConfig
from .blockchain import TheBlockchain from .blockchain import TheBlockchain
class ContractDeployer(ABC): class ContractDeployer:
_contract_name = NotImplemented _contract_name = NotImplemented
_arming_word = "I UNDERSTAND"
class ContractDeploymentError(Exception): class ContractDeploymentError(Exception):
pass pass