Skip to content

Commit

Permalink
Merge pull request #63 from skalenetwork/enhancement/SKALE-1841-wrapp…
Browse files Browse the repository at this point in the history
…ers-for-basic-commands

SKALE-1841 Add wrappers for basic commands in skale.py
  • Loading branch information
badrogger authored Dec 16, 2019
2 parents a063b1e + db91d28 commit faa7f16
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 5 deletions.
2 changes: 1 addition & 1 deletion skale/contracts/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# flake8: noqa

from skale.contracts.base_contract import BaseContract
from skale.contracts.base_contract import BaseContract, transaction_method

from skale.contracts.manager import Manager
from skale.contracts.contract_manager import ContractManager
Expand Down
22 changes: 22 additions & 0 deletions skale/contracts/base_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,30 @@
# along with SKALE.py. If not, see <https://www.gnu.org/licenses/>.
""" SKALE base contract class """

from functools import wraps

from web3 import Web3

from skale.utils.web3_utils import TransactionFailedError, wait_receipt


def transaction_method(transaction):
@wraps(transaction_method)
def wrapper(self, *args, wait_for=False, **kwargs):
res = transaction(self, *args, **kwargs)
if wait_for:
receipt = wait_receipt(self.skale.web3, res['tx'])
if receipt.get('status') == 1:
return receipt
else:
raise TransactionFailedError(
'Transaction {transaction_method.__name__} failed with '
'receipt {receipt}'
)
else:
return res
return wrapper


class BaseContract:
def __init__(self, skale, name, address, abi):
Expand Down
5 changes: 4 additions & 1 deletion skale/contracts/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@
# You should have received a copy of the GNU Affero General Public License
# along with SKALE.py. If not, see <https://www.gnu.org/licenses/>.

from skale.contracts import BaseContract
from skale.contracts import BaseContract, transaction_method
from skale.transactions.tools import post_transaction
from skale.utils.constants import GAS


class Constants(BaseContract):
@transaction_method
def set_periods(self, new_reward_period, new_delta_period):
op = self.contract.functions.setPeriods(new_reward_period, new_delta_period)
tx = post_transaction(self.skale.wallet, op, GAS['set_periods'])
Expand All @@ -34,6 +35,7 @@ def get_reward_period(self):
def get_delta_period(self):
return self.contract.functions.deltaPeriod().call()

@transaction_method
def set_check_time(self, new_check_time):
op = self.contract.functions.setCheckTime(new_check_time)
tx = post_transaction(self.skale.wallet, op, GAS['set_check_time'])
Expand All @@ -42,6 +44,7 @@ def set_check_time(self, new_check_time):
def get_check_time(self):
return self.contract.functions.checkTime().call()

@transaction_method
def set_latency(self, new_allowable_latency):
op = self.contract.functions.setLatency(new_allowable_latency)
tx = post_transaction(self.skale.wallet, op, GAS['set_latency'])
Expand Down
17 changes: 16 additions & 1 deletion skale/contracts/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import socket


from skale.contracts import BaseContract
from skale.contracts import BaseContract, transaction_method
from skale.transactions.tools import post_transaction
from skale.utils import helper
from skale.utils.constants import GAS, NODE_DEPOSIT, OP_TYPES
Expand All @@ -32,6 +32,7 @@


class Manager(BaseContract):
@transaction_method
def create_node(self, ip, port, name, public_ip=None):
logger.info(
f'create_node: {ip}:{port}, public ip: {public_ip} name: {name}')
Expand Down Expand Up @@ -77,6 +78,14 @@ def create_node_data_to_bytes(self, ip, public_ip, port, name, pk, nonce):

return data_bytes

def create_default_schain(self, name):
lifetime = 3600
nodes_type = 4
price_in_wei = self.skale.schains.get_schain_price(nodes_type, lifetime)
return self.create_schain(lifetime, nodes_type, price_in_wei, name,
wait_for=True)

@transaction_method
def create_schain(self, lifetime, type_of_nodes, deposit, name):
logger.info(
f'create_schain: type_of_nodes: {type_of_nodes}, name: {name}')
Expand Down Expand Up @@ -108,33 +117,39 @@ def create_schain_data_to_bytes(self, lifetime, type_of_nodes, name,
)
return data_bytes

@transaction_method
def get_bounty(self, node_id):
op = self.contract.functions.getBounty(node_id)
tx = post_transaction(self.skale.wallet, op, GAS['get_bounty'])
return {'tx': tx}

@transaction_method
def send_verdict(self, validator, node_id, downtime, latency):
op = self.contract.functions.sendVerdict(validator, node_id, downtime,
latency)
tx = post_transaction(self.skale.wallet, op, GAS['send_verdict'])
return {'tx': tx}

@transaction_method
def send_verdicts(self, validator, nodes_ids, downtimes, latencies):
op = self.contract.functions.sendVerdicts(validator, nodes_ids,
downtimes, latencies)
tx = post_transaction(self.skale.wallet, op, GAS['send_verdicts'])
return {'tx': tx}

@transaction_method
def deregister(self, node_id):
op = self.contract.functions.deleteNode(node_id)
tx = post_transaction(self.skale.wallet, op, GAS['delete_node'])
return {'tx': tx}

@transaction_method
def delete_schain(self, schain_name):
op = self.contract.functions.deleteSchain(schain_name)
tx = post_transaction(self.skale.wallet, op, GAS['delete_schain'])
return {'tx': tx}

@transaction_method
def delete_node_by_root(self, node_id):
op = self.contract.functions.deleteNodeByRoot(node_id)
tx = post_transaction(self.skale.wallet, op, GAS['delete_node_by_root'])
Expand Down
4 changes: 3 additions & 1 deletion skale/contracts/token.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@
# along with SKALE.py. If not, see <https://www.gnu.org/licenses/>.
""" SKALE token operations """

from skale.contracts import BaseContract
from skale.contracts import BaseContract, transaction_method
from skale.transactions.tools import post_transaction
from skale.utils.constants import GAS


class Token(BaseContract):
@transaction_method
def transfer(self, address, value):
op = self.contract.functions.send(address, value, b'')
tx = post_transaction(self.skale.wallet, op, GAS['token_transfer'])
Expand All @@ -32,6 +33,7 @@ def transfer(self, address, value):
def get_balance(self, address):
return self.contract.functions.balanceOf(address).call()

@transaction_method
def add_authorized(self, address, wallet): # pragma: no cover
op = self.contract.functions.addAuthorized(address)
tx = post_transaction(self.skale.wallet, op, GAS['token_transfer'])
Expand Down
4 changes: 4 additions & 0 deletions skale/utils/web3_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
logger = logging.getLogger(__name__)


class TransactionFailedError(Exception):
pass


def get_provider(endpoint):
scheme = urlparse(endpoint).scheme
if scheme == 'ws' or scheme == 'wss':
Expand Down
44 changes: 43 additions & 1 deletion tests/contracts/manager_test.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
""" SKALE manager test """

import mock
import pytest
import web3
from hexbytes import HexBytes

import skale.utils.helper as helper
from skale.utils.constants import GAS
from skale.utils.web3_utils import wait_receipt, private_key_to_public
from skale.utils.web3_utils import (wait_receipt, private_key_to_public,
TransactionFailedError)

from tests.constants import DEFAULT_NODE_NAME, SECOND_NODE_NAME
from tests.utils import generate_random_node_data, generate_random_schain_data
Expand Down Expand Up @@ -232,3 +234,43 @@ def test_create_delete_schain(skale):
for sid in schains_ids_after
]
assert name not in schains_names


def test_create_delete_default_schain(skale):
schains_ids = skale.schains_data.get_all_schains_ids()
name = 'default-schain'
res = skale.manager.create_default_schain(name)
assert res['status'] == 1

schains_ids_number_after = skale.schains_data.get_schains_number()
assert schains_ids_number_after == len(schains_ids) + 1
schains_ids_after = skale.schains_data.get_all_schains_ids()

schains_names = [
skale.schains_data.get(sid)['name']
for sid in schains_ids_after
]
assert name in schains_names

res = skale.manager.delete_schain(name, wait_for=True)
assert res['status'] == 1

schains_ids_number_after = skale.schains_data.get_schains_number()
assert schains_ids_number_after == len(schains_ids)
schains_ids_after = skale.schains_data.get_all_schains_ids()

schains_names = [
skale.schains_data.get(sid)['name']
for sid in schains_ids_after
]
assert name not in schains_names


def test_create_node_status_0(skale):
ip, public_ip, port, name = generate_random_node_data()
with mock.patch.object(web3.eth.Eth, 'sendRawTransaction') as send_tx_mock:
send_tx_mock.return_value = b'hexstring'
with mock.patch('skale.contracts.base_contract.wait_receipt',
return_value={'status': 0}):
with pytest.raises(TransactionFailedError):
skale.manager.create_node(ip, port, name, wait_for=True)

0 comments on commit faa7f16

Please sign in to comment.