[KMS-ETH]- Miner and Token config classes for contract deployers

pull/195/head^2
Kieran Prasch 2018-03-07 19:55:12 -08:00
parent 18feef64ec
commit f274b3cb4c
5 changed files with 111 additions and 104 deletions

View File

@ -223,10 +223,7 @@ class Miner(Actor):
class PolicyAuthor(Actor):
"""Alice"""
def __init__(self, address: bytes, policy_agent: PolicyAgent):
if policy_agent.is_deployed is False:
raise PolicyAgent.ContractDeploymentError('PolicyManager contract not deployed.')
def __init__(self, address: bytes, policy_agent):
self.policy_agent = policy_agent
super().__init__(address)
self._arrangements = OrderedDict() # Track authored policies by id

View File

@ -1,5 +1,4 @@
import random
from enum import Enum
from typing import Set, Generator, List
from nkms_eth.actors import PolicyAuthor
@ -37,25 +36,6 @@ class MinerAgent(ContractAgent):
__deployer = MinerEscrowDeployer
_contract_name = __deployer.contract_name
class MinerInfoField(Enum):
MINERS_LENGTH = 0
MINER = 1
VALUE = 2
DECIMALS = 3
LOCKED_VALUE = 4
RELEASE = 5
MAX_RELEASE_PERIODS = 6
RELEASE_RATE = 7
CONFIRMED_PERIODS_LENGTH = 8
CONFIRMED_PERIOD = 9
CONFIRMED_PERIOD_LOCKED_VALUE = 10
LAST_ACTIVE_PERIOD_F = 11
DOWNTIME_LENGTH = 12
DOWNTIME_START_PERIOD = 13
DOWNTIME_END_PERIOD = 14
MINER_IDS_LENGTH = 15
MINER_ID = 16
class NotEnoughUrsulas(Exception):
pass
@ -77,7 +57,6 @@ class MinerAgent(ContractAgent):
count = self.call().getMinerInfo(self.MinerInfoField.MINERS_LENGTH.value, self.null_addr, 0).encode('latin-1')
count = self._blockchain._chain.web3.toInt(count)
for index in range(count):
addr = self.call().getMinerInfo(self.MinerInfoField.MINER.value, self.null_addr, index).encode('latin-1')
yield self._blockchain._chain.web3.toChecksumAddress(addr)
@ -107,8 +86,8 @@ class MinerAgent(ContractAgent):
system_random = random.SystemRandom()
n_select = round(quantity*additional_ursulas) # Select more Ursulas
n_tokens = self.call().getAllLockedTokens()
n_tokens = self.call().getAllLockedTokens() # Check for locked tokens
if not n_tokens > 0:
raise self.NotEnoughUrsulas('There are no locked tokens.')

View File

@ -1,3 +1,4 @@
from enum import Enum
from os.path import dirname, join, abspath
import appdirs
@ -6,13 +7,80 @@ import populus
import nkms_eth
class TokenConfig:
__subdigits = 18
_M = 10 ** __subdigits
__premine = int(1e9) * _M
__saturation = int(1e10) * _M
_reward = __saturation - __premine
@property
def saturation(self):
return self.__saturation
class MinerConfig:
__hours_per_period = 1 # 24 Hours TODO
__min_release_periods = 1 # 30 Periods
__max_awarded_periods = 365 # Periods
__min_allowed_locked = 10 ** 6
__max_allowed_locked = 10 ** 7 * TokenConfig._M
__reward = TokenConfig._reward
__null_addr = '0x' + '0' * 40
__mining_coeff = [
__hours_per_period,
2 * 10 ** 7,
__max_awarded_periods,
__max_awarded_periods,
__min_release_periods,
__min_allowed_locked,
__max_allowed_locked
]
class MinerInfoField(Enum):
MINERS_LENGTH = 0
MINER = 1
VALUE = 2
DECIMALS = 3
LOCKED_VALUE = 4
RELEASE = 5
MAX_RELEASE_PERIODS = 6
RELEASE_RATE = 7
CONFIRMED_PERIODS_LENGTH = 8
CONFIRMED_PERIOD = 9
CONFIRMED_PERIOD_LOCKED_VALUE = 10
LAST_ACTIVE_PERIOD_F = 11
DOWNTIME_LENGTH = 12
DOWNTIME_START_PERIOD = 13
DOWNTIME_END_PERIOD = 14
MINER_IDS_LENGTH = 15
MINER_ID = 16
@property
def null_address(self):
return self.__null_addr
@property
def mining_coefficient(self):
return self.__mining_coeff
@property
def reward(self):
return self.__reward
class PopulusConfig:
def __init__(self):
self._python_project_name = 'nucypher-kms'
def __init__(self, project_name='nucypher-kms', registrar_path=None):
self._python_project_name = project_name
# This config is persistent and is created in user's .local directory
self._registrar_path = join(appdirs.user_data_dir(self._python_project_name), 'registrar.json')
if registrar_path is None:
registrar_path = join(appdirs.user_data_dir(self._python_project_name), 'registrar.json')
self._registrar_path = registrar_path
# Populus project config
self._project_dir = join(dirname(abspath(nkms_eth.__file__)), 'project')

View File

@ -1,24 +1,19 @@
from typing import Tuple
from nkms_eth.agents import MinerAgent
from nkms_eth.base import ContractDeployer
from nkms_eth.token import NuCypherKMSTokenAgent
from nkms_eth.config import MinerConfig, TokenConfig
from .blockchain import TheBlockchain
addr = str
class NuCypherKMSTokenDeployer(ContractDeployer):
__contract_name = 'NuCypherKMSToken'
__subdigits = 18
_M = 10 ** __subdigits
__premine = int(1e9) * _M
__saturation = int(1e10) * _M
_reward = __saturation - __premine
_contract_name = 'NuCypherKMSToken'
def __init__(self, blockchain: TheBlockchain):
def __init__(self, blockchain: TheBlockchain, config=TokenConfig()):
super().__init__(blockchain=blockchain)
self.__creator = self._blockchain._chain.web3.eth.accounts[0]
self._token_config = config
@property
def origin(self):
@ -33,17 +28,17 @@ class NuCypherKMSTokenDeployer(ContractDeployer):
Deployment can only ever be executed exactly once!
"""
if self._armed is False:
if self.is_armed is False:
raise self.ContractDeploymentError('use .arm() to arm the contract, then .deploy().')
if self._contract is not None:
if self.is_deployed is True:
class_name = self.__class__.__name__
message = '{} contract already deployed, use .get() to retrieve it.'.format(class_name)
raise self.ContractDeploymentError(message)
the_nucypherKMS_token_contract, deployment_txhash = self._blockchain._chain.provider.deploy_contract(
self.__contract_name,
deploy_args=[self.__saturation],
self._contract_name,
deploy_args=[self._token_config.saturation],
deploy_transaction={'from': self.origin})
self._blockchain._chain.wait.for_receipt(deployment_txhash, timeout=self._blockchain._timeout)
@ -51,80 +46,44 @@ class NuCypherKMSTokenDeployer(ContractDeployer):
self._contract = the_nucypherKMS_token_contract
return deployment_txhash
def _airdrop(self, amount: int):
"""Airdrops from creator address to all other addresses!"""
_creator, *addresses = self._blockchain._chain.web3.eth.accounts
def txs():
for address in addresses:
yield self._contract.transact({'from': self.origin}).transfer(address, amount * (10 ** 6))
for tx in txs():
self._blockchain._chain.wait.for_receipt(tx, timeout=10)
return self
class PolicyManagerDeployer(ContractDeployer):
__contract_name = 'PolicyManager'
_contract_name = 'PolicyManager'
def __init__(self, escrow: MinerAgent):
super().__init__(escrow)
self.escrow = escrow
self.token = escrow._token
def __init__(self, miner_agent):
super().__init__(miner_agent)
self.miner_agent = miner_agent
self.token_agent = miner_agent._token_agent
def deploy(self) -> Tuple[str, str]:
if self.armed is False:
if self.is_armed is False:
raise self.ContractDeploymentError('PolicyManager contract not armed')
if self.is_deployed is True:
raise self.ContractDeploymentError('PolicyManager contract already deployed')
# Creator deploys the policy manager
the_policy_manager_contract, deploy_txhash = self.blockchain._chain.provider.deploy_contract(
self.__contract_name,
deploy_args=[self.escrow._contract.address],
deploy_transaction={'from': self.token.creator})
the_policy_manager_contract, deploy_txhash = self._blockchain._chain.provider.deploy_contract(
self._contract_name,
deploy_args=[self.miner_agent._contract.address],
deploy_transaction={'from': self.token_agent.creator})
self._contract = the_policy_manager_contract
set_txhash = self.escrow.transact({'from': self.token.creator}).setPolicyManager(the_policy_manager_contract.address)
self.blockchain._chain.wait.for_receipt(set_txhash)
set_txhash = self.miner_agent.transact({'from': self.token_agent.creator}).setPolicyManager(the_policy_manager_contract.address)
self._blockchain._chain.wait.for_receipt(set_txhash)
return deploy_txhash, set_txhash
class MinerEscrowDeployer(ContractDeployer):
__contract_name = 'MinersEscrow'
__hours_per_period = 1 # 24 Hours TODO
__min_release_periods = 1 # 30 Periods
__max_awarded_periods = 365 # Periods
__min_allowed_locked = 10 ** 6
__max_allowed_locked = 10 ** 7 * NuCypherKMSTokenDeployer._M
__reward = NuCypherKMSTokenDeployer._reward
__null_addr = '0x' + '0' * 40
_contract_name = 'MinersEscrow'
__mining_coeff = [
__hours_per_period,
2 * 10 ** 7,
__max_awarded_periods,
__max_awarded_periods,
__min_release_periods,
__min_allowed_locked,
__max_allowed_locked
]
def __init__(self, token: NuCypherKMSTokenAgent):
super().__init__(token)
self._token = token
@property
@classmethod
def null_address(cls):
return cls.__null_addr
def __init__(self, token_agent, config=MinerConfig()):
super().__init__(token_agent)
self._token_agent = token_agent
self._config = config
def deploy(self) -> Tuple[str, str, str]:
"""
@ -137,25 +96,29 @@ class MinerEscrowDeployer(ContractDeployer):
Returns transaction hashes in a tuple: deploy, reward, and initialize.
"""
if self._armed is False:
if self.is_armed is False:
raise self.ContractDeploymentError('use .arm() to arm the contract, then .deploy().')
if self._contract is not None:
if self.is_deployed is True:
class_name = self.__class__.__name__
message = '{} contract already deployed, use .get() to retrieve it.'.format(class_name)
raise self.ContractDeploymentError(message)
the_escrow_contract, deploy_txhash = self._blockchain._chain.provider.deploy_contract(self.__contract_name,
deploy_args=[self._token._contract.address] + self.__mining_coeff,
deploy_transaction={'from': self._token._creator})
deploy_args = [self._token_agent._contract.address] + self._config.mining_coefficient
deploy_tx = {'from': self._token_agent._creator}
the_escrow_contract, deploy_txhash = self._blockchain._chain.provider.deploy_contract(self._contract_name,
deploy_args=deploy_args,
deploy_transaction=deploy_tx)
self._blockchain._chain.wait.for_receipt(deploy_txhash, timeout=self._blockchain._timeout)
self._contract = the_escrow_contract
self.__contract = the_escrow_contract
reward_txhash = self._token.transact({'from': self._token.origin}).transfer(self._contract.address, self.__reward)
reward_txhash = self._token_agent.transact({'from': self._token_agent.origin}).transfer(self.__contract.address,
self._config.reward)
self._blockchain._chain.wait.for_receipt(reward_txhash, timeout=self._blockchain._timeout)
init_txhash = self._contract.transact({'from': self._token.origin}).initialize()
init_txhash = self.__contract.transact({'from': self._token_agent.origin}).initialize()
self._blockchain._chain.wait.for_receipt(init_txhash, timeout=self._blockchain._timeout)
return deploy_txhash, reward_txhash, init_txhash

View File

@ -2,7 +2,7 @@ import pytest
from nkms_eth.agents import NuCypherKMSTokenAgent, MinerAgent
from nkms_eth.deployers import NuCypherKMSTokenDeployer
from tests.utilities import TesterBlockchain, MockMinerEscrow
from tests.utilities import TesterBlockchain, MockMinerEscrowDeployer
@pytest.fixture(scope='function')