mirror of https://github.com/nucypher/nucypher.git
Remove EconomicsFactory/Economics.
parent
2ed9423c57
commit
869ef1fbda
|
@ -29,9 +29,8 @@
|
|||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#
|
||||
import doctest
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
@ -249,7 +248,6 @@ def run_apidoc(_):
|
|||
"tests",
|
||||
"scripts",
|
||||
Path("nucypher", "utilities"),
|
||||
Path("nucypher", "blockchain", "economics.py"),
|
||||
Path("nucypher", "cli"),
|
||||
]
|
||||
for exclusion_item in exclusion_items:
|
||||
|
@ -271,8 +269,6 @@ autodoc_member_order = "bysource"
|
|||
|
||||
# -- Doctest configuration ----------------------------------------
|
||||
|
||||
import doctest
|
||||
|
||||
doctest_default_flags = (0
|
||||
| doctest.DONT_ACCEPT_TRUE_FOR_1
|
||||
| doctest.ELLIPSIS
|
||||
|
|
|
@ -1,119 +0,0 @@
|
|||
from typing import Optional, Tuple
|
||||
|
||||
from web3 import Web3
|
||||
from web3.types import Wei
|
||||
|
||||
from nucypher.blockchain.eth.agents import ContractAgency, TACoApplicationAgent
|
||||
from nucypher.blockchain.eth.registry import BaseContractRegistry
|
||||
from nucypher.blockchain.eth.token import TToken
|
||||
|
||||
|
||||
class Economics:
|
||||
|
||||
_default_min_authorization = TToken(40_000, 'T').to_units()
|
||||
_default_min_operator_seconds = 60 * 60 * 24 # one day in seconds
|
||||
_default_fee_rate = Wei(Web3.to_wei(1, 'gwei'))
|
||||
|
||||
# TODO: Reintroduce Adjudicator
|
||||
# Slashing parameters
|
||||
# HASH_ALGORITHM_KECCAK256 = 0
|
||||
# HASH_ALGORITHM_SHA256 = 1
|
||||
# HASH_ALGORITHM_RIPEMD160 = 2
|
||||
# _default_hash_algorithm = HASH_ALGORITHM_SHA256
|
||||
# _default_base_penalty = 2
|
||||
# _default_penalty_history_coefficient = 0
|
||||
# _default_percentage_penalty_coefficient = 100000 # 0.001%
|
||||
# _default_reward_coefficient = 2
|
||||
|
||||
def __init__(self,
|
||||
min_operator_seconds: int = _default_min_operator_seconds,
|
||||
min_authorization: int = _default_min_authorization,
|
||||
fee_rate: Wei = _default_fee_rate,
|
||||
|
||||
# Adjudicator
|
||||
# hash_algorithm: int = _default_hash_algorithm,
|
||||
# base_penalty: int = _default_base_penalty,
|
||||
# penalty_history_coefficient: int = _default_penalty_history_coefficient,
|
||||
# percentage_penalty_coefficient: int = _default_percentage_penalty_coefficient,
|
||||
# reward_coefficient: int = _default_reward_coefficient
|
||||
):
|
||||
|
||||
"""
|
||||
:param min_operator_seconds: Min amount of seconds while an operator can't be changed
|
||||
:param min_authorization: Amount of minimum allowable authorization
|
||||
|
||||
"""
|
||||
# TODO: Reintroduce Adjudicator
|
||||
# :param hash_algorithm: Hashing algorithm
|
||||
# :param base_penalty: Base for the penalty calculation
|
||||
# :param penalty_history_coefficient: Coefficient for calculating the penalty depending on the history
|
||||
# :param percentage_penalty_coefficient: Coefficient for calculating the percentage penalty
|
||||
# :param reward_coefficient: Coefficient for calculating the reward
|
||||
|
||||
# self.hash_algorithm = hash_algorithm
|
||||
# self.base_penalty = base_penalty
|
||||
# self.penalty_history_coefficient = penalty_history_coefficient
|
||||
# self.percentage_penalty_coefficient = percentage_penalty_coefficient
|
||||
# self.reward_coefficient = reward_coefficient
|
||||
|
||||
self.min_operator_seconds = min_operator_seconds
|
||||
self.min_authorization = min_authorization
|
||||
self.fee_rate = fee_rate
|
||||
|
||||
@property
|
||||
def taco_application_deployment_parameters(self) -> Tuple[int, ...]:
|
||||
"""Cast coefficient attributes to uint256 compatible type for solidity+EVM"""
|
||||
deploy_parameters = ( # note: order-sensitive
|
||||
self.min_authorization,
|
||||
self.min_operator_seconds,
|
||||
)
|
||||
return tuple(map(int, deploy_parameters))
|
||||
|
||||
# TODO: Reintroduce Adjudicator
|
||||
# @property
|
||||
# def slashing_deployment_parameters(self) -> Tuple[int, ...]:
|
||||
# """Cast coefficient attributes to uint256 compatible type for solidity+EVM"""
|
||||
# deployment_parameters = [
|
||||
# self.hash_algorithm,
|
||||
# self.base_penalty,
|
||||
# self.penalty_history_coefficient,
|
||||
# self.percentage_penalty_coefficient,
|
||||
# self.reward_coefficient
|
||||
# ]
|
||||
# return tuple(map(int, deployment_parameters))
|
||||
|
||||
|
||||
class EconomicsFactory:
|
||||
# TODO: Enforce singleton
|
||||
|
||||
__economics = dict()
|
||||
|
||||
@classmethod
|
||||
def get_economics(cls, registry: BaseContractRegistry, eth_provider_uri: Optional[str] = None) -> Economics:
|
||||
registry_id = registry.id
|
||||
try:
|
||||
return cls.__economics[registry_id]
|
||||
except KeyError:
|
||||
economics = EconomicsFactory.retrieve_from_blockchain(registry=registry, eth_provider_uri=eth_provider_uri)
|
||||
cls.__economics[registry_id] = economics
|
||||
return economics
|
||||
|
||||
@staticmethod
|
||||
def retrieve_from_blockchain(registry: BaseContractRegistry, eth_provider_uri: Optional[str] = None) -> Economics:
|
||||
|
||||
# Agents
|
||||
application_agent = ContractAgency.get_agent(
|
||||
TACoApplicationAgent, registry=registry, provider_uri=eth_provider_uri
|
||||
)
|
||||
|
||||
# TACo Application
|
||||
min_authorization = application_agent.get_min_authorization()
|
||||
min_operator_seconds = application_agent.get_min_operator_seconds()
|
||||
|
||||
# Aggregate
|
||||
economics_parameters = dict(min_authorization=min_authorization,
|
||||
min_operator_seconds=min_operator_seconds)
|
||||
|
||||
economics = Economics(**economics_parameters)
|
||||
|
||||
return economics
|
|
@ -27,7 +27,6 @@ from web3 import HTTPProvider, Web3
|
|||
from web3.types import TxReceipt
|
||||
|
||||
from nucypher.acumen.nicknames import Nickname
|
||||
from nucypher.blockchain.economics import Economics
|
||||
from nucypher.blockchain.eth.agents import (
|
||||
AdjudicatorAgent,
|
||||
ContractAgency,
|
||||
|
@ -71,13 +70,13 @@ class BaseActor:
|
|||
pass
|
||||
|
||||
@validate_checksum_address
|
||||
def __init__(self,
|
||||
domain: Optional[str],
|
||||
registry: BaseContractRegistry,
|
||||
transacting_power: Optional[TransactingPower] = None,
|
||||
checksum_address: Optional[ChecksumAddress] = None,
|
||||
economics: Optional[Economics] = None):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
domain: Optional[str],
|
||||
registry: BaseContractRegistry,
|
||||
transacting_power: Optional[TransactingPower] = None,
|
||||
checksum_address: Optional[ChecksumAddress] = None,
|
||||
):
|
||||
if not (bool(checksum_address) ^ bool(transacting_power)):
|
||||
error = f'Pass transacting power or checksum address, got {checksum_address} and {transacting_power}.'
|
||||
raise ValueError(error)
|
||||
|
@ -94,7 +93,6 @@ class BaseActor:
|
|||
else:
|
||||
self.checksum_address = checksum_address
|
||||
|
||||
self.economics = economics or Economics()
|
||||
self.transacting_power = transacting_power
|
||||
self.registry = registry
|
||||
self.network = domain
|
||||
|
|
|
@ -10,7 +10,6 @@ from cryptography.exceptions import InternalError
|
|||
from eth_utils import to_checksum_address
|
||||
from nucypher_core.umbral import PublicKey
|
||||
|
||||
from nucypher.blockchain.economics import Economics
|
||||
from nucypher.blockchain.eth.networks import NetworksInventory
|
||||
from nucypher.blockchain.eth.token import TToken
|
||||
from nucypher.policy.payment import PRE_PAYMENT_METHODS
|
||||
|
@ -128,7 +127,8 @@ EIP55_CHECKSUM_ADDRESS = ChecksumAddress()
|
|||
WEI = click.IntRange(min=1, clamp=False) # TODO: Better validation for ether and wei values?
|
||||
GWEI = DecimalRange(min=0)
|
||||
|
||||
__min_authorization = TToken.from_units(Economics._default_min_authorization).to_tokens()
|
||||
|
||||
__min_authorization = TToken(40_000, "T").to_tokens() # TODO right spot for this?
|
||||
MIN_AUTHORIZATION = Decimal(__min_authorization)
|
||||
STAKED_TOKENS_RANGE = DecimalRange(min=__min_authorization)
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ from nucypher.blockchain.eth.agents import ContractAgency, TACoApplicationAgent
|
|||
from tests.constants import TEST_ETH_PROVIDER_URI
|
||||
|
||||
|
||||
def test_get_agent_with_different_registries(application_economics, test_registry, agency_local_registry):
|
||||
def test_get_agent_with_different_registries(test_registry, agency_local_registry):
|
||||
# Get agents using same registry instance
|
||||
application_agent_1 = ContractAgency.get_agent(
|
||||
TACoApplicationAgent,
|
||||
|
|
|
@ -4,14 +4,17 @@
|
|||
import pytest
|
||||
from eth_tester.exceptions import TransactionFailed
|
||||
|
||||
from nucypher.blockchain.eth.agents import NucypherTokenAgent, ContractAgency
|
||||
from nucypher.blockchain.eth.agents import ContractAgency, NucypherTokenAgent
|
||||
from nucypher.blockchain.eth.signers.software import Web3Signer
|
||||
from nucypher.crypto.powers import TransactingPower
|
||||
from tests.constants import TEST_ETH_PROVIDER_URI
|
||||
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def agent(testerchain, test_registry) -> NucypherTokenAgent:
|
||||
token_agent = ContractAgency.get_agent(NucypherTokenAgent, registry=test_registry)
|
||||
token_agent = ContractAgency.get_agent(
|
||||
NucypherTokenAgent, registry=test_registry, provider_uri=TEST_ETH_PROVIDER_URI
|
||||
)
|
||||
return token_agent
|
||||
|
||||
|
||||
|
@ -38,50 +41,54 @@ def test_token_properties(agent):
|
|||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_get_balance(agent, application_economics):
|
||||
def test_get_balance(agent):
|
||||
testerchain = agent.blockchain
|
||||
deployer, someone, *everybody_else = testerchain.client.accounts
|
||||
balance = agent.get_balance(address=someone)
|
||||
assert balance == 0
|
||||
balance = agent.get_balance(address=deployer)
|
||||
assert balance == application_economics.erc20_total_supply
|
||||
assert balance > 0
|
||||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_approve_transfer(agent, application_economics):
|
||||
def test_approve_transfer(agent, taco_application_agent):
|
||||
testerchain = agent.blockchain
|
||||
deployer, someone, *everybody_else = testerchain.client.accounts
|
||||
tpower = TransactingPower(account=someone, signer=Web3Signer(testerchain.client))
|
||||
|
||||
# Approve
|
||||
receipt = agent.approve_transfer(amount=application_economics.min_authorization,
|
||||
spender_address=agent.contract_address,
|
||||
transacting_power=tpower)
|
||||
receipt = agent.approve_transfer(
|
||||
amount=taco_application_agent.get_min_authorization(),
|
||||
spender_address=agent.contract_address,
|
||||
transacting_power=tpower,
|
||||
)
|
||||
|
||||
assert receipt['status'] == 1, "Transaction Rejected"
|
||||
assert receipt['logs'][0]['address'] == agent.contract_address
|
||||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_transfer(agent, application_economics):
|
||||
def test_transfer(agent, taco_application_agent):
|
||||
testerchain = agent.blockchain
|
||||
origin, someone, *everybody_else = testerchain.client.accounts
|
||||
tpower = TransactingPower(account=origin, signer=Web3Signer(testerchain.client))
|
||||
|
||||
old_balance = agent.get_balance(someone)
|
||||
receipt = agent.transfer(amount=application_economics.min_authorization,
|
||||
target_address=someone,
|
||||
transacting_power=tpower)
|
||||
receipt = agent.transfer(
|
||||
amount=taco_application_agent.get_min_authorization(),
|
||||
target_address=someone,
|
||||
transacting_power=tpower,
|
||||
)
|
||||
|
||||
assert receipt['status'] == 1, "Transaction Rejected"
|
||||
assert receipt['logs'][0]['address'] == agent.contract_address
|
||||
|
||||
new_balance = agent.get_balance(someone)
|
||||
assert new_balance == old_balance + application_economics.min_authorization
|
||||
assert new_balance == old_balance + taco_application_agent.get_min_authorization()
|
||||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_approve_and_call(agent, application_economics, deploy_contract):
|
||||
def test_approve_and_call(agent, taco_application_agent, deploy_contract):
|
||||
testerchain = agent.blockchain
|
||||
deployer, someone, *everybody_else = testerchain.client.accounts
|
||||
|
||||
|
@ -90,14 +97,19 @@ def test_approve_and_call(agent, application_economics, deploy_contract):
|
|||
# Approve and call
|
||||
tpower = TransactingPower(account=someone, signer=Web3Signer(testerchain.client))
|
||||
call_data = b"Good morning, that's a nice tnetennba."
|
||||
receipt = agent.approve_and_call(amount=application_economics.min_authorization,
|
||||
target_address=mock_target.address,
|
||||
transacting_power=tpower,
|
||||
call_data=call_data)
|
||||
receipt = agent.approve_and_call(
|
||||
amount=taco_application_agent.get_min_authorization(),
|
||||
target_address=mock_target.address,
|
||||
transacting_power=tpower,
|
||||
call_data=call_data,
|
||||
)
|
||||
|
||||
assert receipt['status'] == 1, "Transaction Rejected"
|
||||
assert receipt['logs'][0]['address'] == agent.contract_address
|
||||
|
||||
assert mock_target.functions.extraData().call() == call_data
|
||||
assert mock_target.functions.sender().call() == someone
|
||||
assert mock_target.functions.value().call() == application_economics.min_authorization
|
||||
assert (
|
||||
mock_target.functions.value().call()
|
||||
== taco_application_agent.get_min_authorization()
|
||||
)
|
||||
|
|
|
@ -18,7 +18,6 @@ from twisted.internet.task import Clock
|
|||
from web3 import Web3
|
||||
|
||||
import tests
|
||||
from nucypher.blockchain.economics import Economics
|
||||
from nucypher.blockchain.eth.actors import Operator
|
||||
from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory
|
||||
from nucypher.blockchain.eth.registry import LocalContractRegistry
|
||||
|
@ -171,7 +170,7 @@ def bob_test_config(testerchain, test_registry):
|
|||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def idle_policy(testerchain, alice, bob, application_economics):
|
||||
def idle_policy(testerchain, alice, bob):
|
||||
"""Creates a Policy, in a manner typical of how Alice might do it, with a unique label"""
|
||||
random_label = generate_random_label()
|
||||
expiration = maya.now() + timedelta(days=1)
|
||||
|
@ -304,12 +303,6 @@ def lonely_ursula_maker(ursula_test_config, testerchain):
|
|||
#
|
||||
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def application_economics():
|
||||
economics = Economics()
|
||||
return economics
|
||||
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def mock_testerchain() -> MockBlockchain:
|
||||
BlockchainInterfaceFactory._interfaces = dict()
|
||||
|
@ -366,8 +359,10 @@ def policy_rate():
|
|||
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def policy_value(application_economics, policy_rate):
|
||||
value = policy_rate * application_economics.min_operator_seconds
|
||||
def policy_value(policy_rate):
|
||||
# TODO constant?
|
||||
min_operator_seconds = 60 * 60 * 24 # one day in seconds
|
||||
value = policy_rate * min_operator_seconds
|
||||
return value
|
||||
|
||||
|
||||
|
|
|
@ -1,27 +1,13 @@
|
|||
|
||||
|
||||
from decimal import Decimal, InvalidOperation
|
||||
|
||||
import pytest
|
||||
from decimal import Decimal, InvalidOperation
|
||||
|
||||
from nucypher.blockchain.eth.token import NU
|
||||
|
||||
|
||||
def test_NU(application_economics):
|
||||
|
||||
# Starting Small
|
||||
min_allowed_locked = NU(application_economics.min_authorization, 'NuNit')
|
||||
assert application_economics.min_authorization == int(min_allowed_locked.to_units())
|
||||
|
||||
min_NU_locked = int(str(application_economics.min_authorization)[0:-18])
|
||||
expected = NU(min_NU_locked, 'NU')
|
||||
assert min_allowed_locked == expected
|
||||
|
||||
# TODO: Use minimums for T staking
|
||||
# Starting Big
|
||||
# min_allowed_locked = NU(min_NU_locked, 'NU')
|
||||
# assert token_economics.min_authorization == int(min_allowed_locked)
|
||||
# assert token_economics.min_authorization == int(min_allowed_locked.to_units())
|
||||
# assert str(min_allowed_locked) == '40000 NU'
|
||||
def test_NU():
|
||||
|
||||
# Alternate construction
|
||||
assert NU(1, 'NU') == NU('1.0', 'NU') == NU(1.0, 'NU')
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
import pytest
|
||||
|
||||
from nucypher.blockchain.economics import EconomicsFactory
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('testerchain')
|
||||
def test_retrieving_from_blockchain(application_economics, test_registry):
|
||||
economics = EconomicsFactory.get_economics(registry=test_registry)
|
||||
assert (
|
||||
economics.taco_application_deployment_parameters
|
||||
== application_economics.taco_application_deployment_parameters
|
||||
)
|
|
@ -53,7 +53,7 @@ COORDINATOR = MockCoordinatorAgent(MockBlockchain())
|
|||
|
||||
|
||||
@pytest.fixture(scope="function", autouse=True)
|
||||
def mock_coordinator_agent(testerchain, application_economics, mock_contract_agency):
|
||||
def mock_coordinator_agent(testerchain, mock_contract_agency):
|
||||
mock_contract_agency._MockContractAgency__agents[CoordinatorAgent] = COORDINATOR
|
||||
|
||||
yield COORDINATOR
|
||||
|
|
|
@ -5,7 +5,6 @@ from typing import Iterable, Optional
|
|||
import pytest
|
||||
from eth_account.account import Account
|
||||
|
||||
from nucypher.blockchain.economics import EconomicsFactory
|
||||
from nucypher.blockchain.eth.actors import Operator
|
||||
from nucypher.blockchain.eth.agents import (
|
||||
AdjudicatorAgent,
|
||||
|
@ -149,10 +148,8 @@ def test_registry_source_manager(testerchain, test_registry):
|
|||
|
||||
|
||||
@pytest.fixture(scope='module', autouse=True)
|
||||
def mock_contract_agency(module_mocker, application_economics):
|
||||
def mock_contract_agency():
|
||||
# Patch
|
||||
module_mocker.patch.object(EconomicsFactory, 'get_economics', return_value=application_economics)
|
||||
|
||||
from tests.mock.agents import MockContractAgency
|
||||
|
||||
# Monkeypatch # TODO: Use better tooling for this monkeypatch?
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import pytest
|
||||
from nucypher_core.ferveo import Keypair, Validator
|
||||
|
||||
from nucypher.blockchain.economics import EconomicsFactory
|
||||
from nucypher.blockchain.eth.actors import Operator
|
||||
from nucypher.blockchain.eth.agents import ContractAgency
|
||||
from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory
|
||||
|
@ -34,11 +33,7 @@ def mock_transacting_power(module_mocker):
|
|||
|
||||
|
||||
@pytest.fixture(scope='module', autouse=True)
|
||||
def mock_contract_agency(module_mocker, application_economics):
|
||||
|
||||
# Patch
|
||||
module_mocker.patch.object(EconomicsFactory, 'get_economics', return_value=application_economics)
|
||||
|
||||
def mock_contract_agency():
|
||||
from tests.mock.agents import MockContractAgency
|
||||
|
||||
# Monkeypatch # TODO: Use better tooling for this monkeypatch?
|
||||
|
|
|
@ -6,7 +6,6 @@ from eth_tester.exceptions import TransactionFailed
|
|||
from hexbytes import HexBytes
|
||||
from web3 import Web3
|
||||
|
||||
from nucypher.blockchain.economics import Economics
|
||||
from nucypher.blockchain.eth.interfaces import (
|
||||
BlockchainInterface,
|
||||
)
|
||||
|
@ -74,9 +73,6 @@ class TesterBlockchain(BlockchainInterface):
|
|||
__OPERATORS_RANGE = range(NUMBER_OF_URSULAS_IN_BLOCKCHAIN_TESTS)
|
||||
__ACCOUNT_CACHE = list()
|
||||
|
||||
# Defaults
|
||||
DEFAULT_ECONOMICS = Economics()
|
||||
|
||||
def __init__(self,
|
||||
test_accounts: int = NUMBER_OF_ETH_TEST_ACCOUNTS,
|
||||
poa: bool = True,
|
||||
|
|
Loading…
Reference in New Issue