mirror of https://github.com/nucypher/nucypher.git
[KMS-ETH]- Miner and Token config classes for contract deployers
parent
18feef64ec
commit
f274b3cb4c
|
@ -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
|
||||
|
|
|
@ -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.')
|
||||
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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')
|
||||
|
|
Loading…
Reference in New Issue