Skip to content

Commit

Permalink
[FIX-#238] Cross-Check Custom Token and UDC Values
Browse files Browse the repository at this point in the history
  • Loading branch information
Nils Diefenbach committed Aug 22, 2019
1 parent 50bcbe4 commit 7e303e9
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 4 deletions.
8 changes: 8 additions & 0 deletions scenario_player/exceptions/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@ class ConfigurationError(ValueError):
"""Generic error thrown if there was an error while reading the scenario file."""


class UDCTokenConfigError(ConfigurationError):
"""Invalid Configuration parameters. Most likely there is an issue with Token amounts"""


class InsufficientMintingAmount(ConfigurationError):
"""The minted amount set in token.min_balance is not sufficient"""


class NodeConfigurationError(ConfigurationError):
"""An error occurred while validating the nodes setting of a scenario file."""

Expand Down
15 changes: 15 additions & 0 deletions scenario_player/scenario.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import yaml

from scenario_player.constants import GAS_LIMIT_FOR_TOKEN_CONTRACT_CALL
from scenario_player.exceptions.config import InsufficientMintingAmount
from scenario_player.utils.configuration import (
NodesConfig,
ScenarioConfig,
Expand Down Expand Up @@ -33,10 +34,24 @@ def __init__(self, yaml_path: pathlib.Path, data_path: pathlib.Path) -> None:
self.scenario = ScenarioConfig(self._loaded)
self.token = TokenConfig(self._loaded, data_path.joinpath("token.info"))
self.spaas = SPaaSConfig(self._loaded)
self.validate()

self.gas_limit = GAS_LIMIT_FOR_TOKEN_CONTRACT_CALL * 2

@property
def name(self) -> str:
"""Return the name of the scenario file, sans extension."""
return self.path.stem

def validate(self):
"""Validate cross-config section requirements of the scenario.
:raises InsufficientMintingAmount:
If token.min_balance < settings.services.udc.token.max_funding
"""

# Check that the amount of minted tokens is >= than the amount of deposited tokens
try:
assert self.token.min_balance >= self.settings.services.udc.token.max_funding
except AssertionError:
raise InsufficientMintingAmount
6 changes: 5 additions & 1 deletion scenario_player/utils/configuration/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
import structlog

from scenario_player.constants import GAS_STRATEGIES, TIMEOUT
from scenario_player.exceptions.config import ScenarioConfigurationError, ServiceConfigurationError
from scenario_player.exceptions.config import (
ScenarioConfigurationError,
ServiceConfigurationError,
UDCTokenConfigError,
)
from scenario_player.utils.configuration.base import ConfigMapping

log = structlog.get_logger(__name__)
Expand Down
7 changes: 6 additions & 1 deletion scenario_player/utils/token.py
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,10 @@ def effective_balance(self, at_target):
"""Get the effective balance of the target address."""
return self.contract_proxy.contract.functions.effectiveBalance(at_target).call()

def total_deposit(self, at_target):
""""Get the so far deposted amount"""
return self.contract_proxy.contract.functions.total_deposit(at_target).call()

def mint(self, target_address) -> Union[str, None]:
"""The mint function isn't present on the UDC, pass the UDTC address instead."""
return super(UserDepositContract, self).mint(
Expand Down Expand Up @@ -397,6 +401,7 @@ def deposit(self, target_address) -> Union[str, None]:
TODO: Allow setting max funding parameter, similar to the token `funding_min` setting.
"""
balance = self.effective_balance(target_address)
total_deposit = self.total_deposit(target_address)
min_deposit = self.config.settings.services.udc.token.balance_per_node
max_funding = self.config.settings.services.udc.token.max_funding
log.debug(
Expand All @@ -409,6 +414,6 @@ def deposit(self, target_address) -> Union[str, None]:
return

log.debug("deposit call required - insufficient funds")
deposit_amount = max_funding - balance
deposit_amount = total_deposit + (max_funding - balance)
params = {"amount": deposit_amount, "target_address": target_address}
return self.transact("deposit", params)
28 changes: 26 additions & 2 deletions tests/unittests/utils/configuration/test_settings.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from unittest.mock import patch

import pytest
import yaml
from web3.gas_strategies.time_based import fast_gas_price_strategy, medium_gas_price_strategy

from scenario_player.exceptions.config import InsufficientMintingAmount, UDCTokenConfigError
from scenario_player.scenario import ScenarioYAML
from scenario_player.utils.configuration.base import ConfigMapping
from scenario_player.utils.configuration.settings import (
PFSSettingsConfig,
Expand All @@ -14,6 +15,16 @@
)


@pytest.fixture()
def file_for_insufficient_minting_test(tmp_path, minimal_yaml_dict):
minimal_yaml_dict["settings"] = {"services": {"udc": {"token": {"max_funding": 6000}}}}
minimal_yaml_dict["token"] = {"min_balance": 5999}
tmp_file = tmp_path.joinpath("tmp.yaml")
with open(tmp_file, "w") as outfile:
yaml.dump(minimal_yaml_dict, outfile, default_flow_style=False)
yield tmp_file


class TestSettingsConfig:
def test_is_subclass_of_config_mapping(self, minimal_yaml_dict):
"""The class is a subclass of :class:`ConfigMapping`."""
Expand Down Expand Up @@ -158,3 +169,16 @@ def test_attributes_whose_key_is_absent_return_expected_default(
config = UDCTokenSettings(minimal_yaml_dict)
MISSING = object()
assert getattr(config, key, MISSING) == expected

def test_balance_per_node_must_not_be_greater_than_max_funding(self, minimal_yaml_dict):
minimal_yaml_dict["settings"] = {
"services": {"udc": {"token": {"max_funding": 6000, "balance_per_node": 6001}}}
}
with pytest.raises(UDCTokenConfigError):
UDCTokenSettings(minimal_yaml_dict)

def test_insufficient_minting(self, file_for_insufficient_minting_test):
with pytest.raises(InsufficientMintingAmount):
ScenarioYAML(
file_for_insufficient_minting_test, file_for_insufficient_minting_test.parent
)

0 comments on commit 7e303e9

Please sign in to comment.