Skip to content

Commit

Permalink
Merge pull request #163 from skalenetwork/enhancement/SKALE-2430-retr…
Browse files Browse the repository at this point in the history
…y-helpers

Enhancement/skale 2430 retry helpers
  • Loading branch information
badrogger authored May 7, 2020
2 parents 583fbb5 + a5820ab commit ee8b1e6
Show file tree
Hide file tree
Showing 14 changed files with 121 additions and 66 deletions.
60 changes: 31 additions & 29 deletions skale/contracts/base_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
""" SKALE base contract class """

import logging
from functools import wraps
from functools import partial, wraps

from web3 import Web3

Expand All @@ -31,38 +31,40 @@
logger = logging.getLogger(__name__)


def transaction_method(gas_limit):
def real_decorator(transaction):
@wraps(transaction)
def wrapper(self, *args, wait_for=True, timeout=4, blocks_to_wait=50,
gas_price=None, nonce=None,
dry_run_only=False, skip_dry_run=False,
raise_for_status=True, **kwargs):
method = transaction(self, *args, **kwargs)
tx_res = TxRes()
if not skip_dry_run:
tx_res.dry_run_result = make_dry_run_call(self.skale.wallet,
method, gas_limit)
def transaction_method(transaction=None, *, gas_limit=10):
if transaction is None:
return partial(transaction_method, gas_limit=gas_limit)

if not dry_run_only and (skip_dry_run or tx_res.dry_run_passed()):
gas_price = gas_price or self.skale.gas_price
tx_res.hash = post_transaction(self.skale.wallet, method,
gas_limit, gas_price, nonce)
if wait_for:
tx_res.receipt = wait_for_receipt_by_blocks(
self.skale.web3,
tx_res.hash,
timeout=timeout,
blocks_to_wait=blocks_to_wait
)
@wraps(transaction)
def wrapper(self, *args, wait_for=True,
wait_timeout=4, blocks_to_wait=50,
gas_price=None, nonce=None,
dry_run_only=False, skip_dry_run=False, raise_for_status=True,
**kwargs):
method = transaction(self, *args, **kwargs)
tx_res = TxRes()
if not skip_dry_run:
tx_res.dry_run_result = make_dry_run_call(self.skale.wallet,
method, gas_limit)

if raise_for_status:
tx_res.raise_for_status()
if not dry_run_only and (skip_dry_run or tx_res.dry_run_passed()):
gas_price = gas_price or self.skale.gas_price
tx_res.hash = post_transaction(self.skale.wallet, method,
gas_limit, gas_price, nonce)
if wait_for:
tx_res.receipt = wait_for_receipt_by_blocks(
self.skale.web3,
tx_res.hash,
timeout=wait_timeout,
blocks_to_wait=blocks_to_wait
)

return tx_res
if raise_for_status:
tx_res.raise_for_status()

return wrapper
return real_decorator
return tx_res

return wrapper


class BaseContract:
Expand Down
10 changes: 5 additions & 5 deletions skale/contracts/constants_holder.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@


class ConstantsHolder(BaseContract):
@transaction_method(GAS['set_periods'])
@transaction_method(gas_limit=GAS['set_periods'])
def set_periods(self, new_reward_period, new_delta_period):
return self.contract.functions.setPeriods(new_reward_period, new_delta_period)

Expand All @@ -32,14 +32,14 @@ def get_reward_period(self):
def get_delta_period(self):
return self.contract.functions.deltaPeriod().call()

@transaction_method(GAS['set_check_time'])
@transaction_method(gas_limit=GAS['set_check_time'])
def set_check_time(self, new_check_time):
return self.contract.functions.setCheckTime(new_check_time)

def get_check_time(self):
return self.contract.functions.checkTime().call()

@transaction_method(GAS['set_latency'])
@transaction_method(gas_limit=GAS['set_latency'])
def set_latency(self, new_allowable_latency):
return self.contract.functions.setLatency(new_allowable_latency)

Expand All @@ -54,14 +54,14 @@ def msr(self) -> int:
"""
return self.contract.functions.msr().call()

@transaction_method(GAS['set_msr'])
@transaction_method(gas_limit=GAS['set_msr'])
def _set_msr(self, new_msr: int) -> None:
"""For internal usage only"""
return self.contract.functions.setMSR(new_msr)

def get_launch_timestamp(self) -> int:
return self.contract.functions.launchTimestamp().call()

@transaction_method(GAS['set_launch_timestamp'])
@transaction_method(gas_limit=GAS['set_launch_timestamp'])
def set_launch_timestamp(self, launch_timestamp: int):
return self.contract.functions.setLaunchTimestamp(launch_timestamp)
8 changes: 4 additions & 4 deletions skale/contracts/delegation/delegation_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ def get_all_delegations_by_validator(self, validator_id: int) -> list:
delegation_ids = self._get_delegation_ids_by_validator(validator_id)
return self.get_all_delegations(delegation_ids)

@transaction_method(GAS['delegate'])
@transaction_method(gas_limit=GAS['delegate'])
def delegate(self, validator_id: int, amount: int, delegation_period: int, info: str) -> TxRes:
"""Creates request to delegate amount of tokens to validator_id.
Expand All @@ -143,7 +143,7 @@ def delegate(self, validator_id: int, amount: int, delegation_period: int, info:
"""
return self.contract.functions.delegate(validator_id, amount, delegation_period, info)

@transaction_method(GAS['accept_pending_delegation'])
@transaction_method(gas_limit=GAS['accept_pending_delegation'])
def accept_pending_delegation(self, delegation_id: int) -> TxRes:
"""Accepts a pending delegation by delegation ID.
Expand All @@ -154,7 +154,7 @@ def accept_pending_delegation(self, delegation_id: int) -> TxRes:
"""
return self.contract.functions.acceptPendingDelegation(delegation_id)

@transaction_method(GAS['cancel_pending_delegation'])
@transaction_method(gas_limit=GAS['cancel_pending_delegation'])
def cancel_pending_delegation(self, delegation_id: int) -> TxRes:
"""Cancel pending delegation request.
Expand All @@ -165,7 +165,7 @@ def cancel_pending_delegation(self, delegation_id: int) -> TxRes:
"""
return self.contract.functions.cancelPendingDelegation(delegation_id)

@transaction_method(GAS['request_undelegation'])
@transaction_method(gas_limit=GAS['request_undelegation'])
def request_undelegation(self, delegation_id: int) -> TxRes:
""" This method is for undelegating request in the end of
delegation period (3/6/12 months)
Expand Down
4 changes: 2 additions & 2 deletions skale/contracts/delegation/distributor.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def get_earned_fee_amount(self, address: str) -> dict:
'from': address
})

@transaction_method(GAS['withdraw_bounty'])
@transaction_method(gas_limit=GAS['withdraw_bounty'])
def withdraw_bounty(self, validator_id: int, to: str) -> TxRes:
"""Withdraw earned bounty to specified address
Expand All @@ -75,7 +75,7 @@ def withdraw_bounty(self, validator_id: int, to: str) -> TxRes:
"""
return self.contract.functions.withdrawBounty(validator_id, to)

@transaction_method(GAS['withdraw_fee'])
@transaction_method(gas_limit=GAS['withdraw_fee'])
def withdraw_fee(self, to: str) -> TxRes:
"""Withdraw earned fee to specified address
Expand Down
10 changes: 5 additions & 5 deletions skale/contracts/delegation/validator_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,12 +157,12 @@ def get_validator_node_indices(self, validator_id: int) -> list:
"""
return self.contract.functions.getValidatorNodeIndexes(validator_id).call()

@transaction_method(GAS['enable_validator'])
@transaction_method(gas_limit=GAS['enable_validator'])
def _enable_validator(self, validator_id: int) -> TxRes:
"""For internal usage only"""
return self.contract.functions.enableValidator(validator_id)

@transaction_method(GAS['disable_validator'])
@transaction_method(gas_limit=GAS['disable_validator'])
def _disable_validator(self, validator_id: int) -> TxRes:
"""For internal usage only"""
return self.contract.functions.disableValidator(validator_id)
Expand All @@ -175,7 +175,7 @@ def is_accepting_new_requests(self, validator_id: int) -> bool:
"""For internal usage only"""
return self.contract.functions.isAcceptingNewRequests(validator_id).call()

@transaction_method(GAS['register_validator'])
@transaction_method(gas_limit=GAS['register_validator'])
def register_validator(self, name: str, description: str, fee_rate: int,
min_delegation_amount: int) -> TxRes:
"""Registers a new validator in the SKALE Manager contracts.
Expand All @@ -199,7 +199,7 @@ def get_link_node_signature(self, validator_id: int) -> str:
signed_hash = self.skale.wallet.sign_hash(unsigned_hash.hex())
return signed_hash.signature.hex()

@transaction_method(GAS['link_node_address'])
@transaction_method(gas_limit=GAS['link_node_address'])
def link_node_address(self, node_address: str, signature: str) -> TxRes:
"""Link node address to your validator account.
Expand All @@ -212,7 +212,7 @@ def link_node_address(self, node_address: str, signature: str) -> TxRes:
"""
return self.contract.functions.linkNodeAddress(node_address, signature)

@transaction_method(GAS['unlink_node_address'])
@transaction_method(gas_limit=GAS['unlink_node_address'])
def unlink_node_address(self, node_address: str) -> TxRes:
"""Unlink node address from your validator account.
Expand Down
13 changes: 9 additions & 4 deletions skale/contracts/dkg.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,32 +18,37 @@
# along with SKALE.py. If not, see <https://www.gnu.org/licenses/>.

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


class DKG(BaseContract):
def gas_price(self):
return self.skale.gas_price * 5 // 4

@transaction_method(GAS['dkg_broadcast'])
@retry_tx
@transaction_method(gas_limit=GAS['dkg_broadcast'])
def broadcast(self, group_index, node_index,
verification_vector, secret_key_contribution):
return self.contract.functions.broadcast(group_index, node_index,
verification_vector,
secret_key_contribution)

@transaction_method(GAS['dkg_response'])
@retry_tx
@transaction_method(gas_limit=GAS['dkg_response'])
def response(self, group_index, from_node_index,
secret_number, multiplied_share):
return self.contract.functions.response(group_index, from_node_index,
secret_number,
multiplied_share)

@transaction_method(GAS['dkg_alright'])
@retry_tx
@transaction_method(gas_limit=GAS['dkg_alright'])
def alright(self, group_index, from_node_index):
return self.contract.functions.alright(group_index, from_node_index)

@transaction_method(GAS['dkg_complaint'])
@retry_tx
@transaction_method(gas_limit=GAS['dkg_complaint'])
def complaint(self, group_index, from_node_index, to_node_index):
return self.contract.functions.complaint(group_index, from_node_index,
to_node_index)
20 changes: 11 additions & 9 deletions skale/contracts/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@


class Manager(BaseContract):
@transaction_method(GAS['create_node'])

@transaction_method(gas_limit=GAS['create_node'])
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 @@ -74,11 +75,12 @@ def create_node_data_to_bytes(self, ip, public_ip, port, name, pk, nonce):
def create_default_schain(self, name):
lifetime = 3600
nodes_type = 4
price_in_wei = self.skale.schains.get_schain_price(nodes_type, lifetime)
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(GAS['create_schain'])
@transaction_method(gas_limit=GAS['create_schain'])
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,28 +110,28 @@ def create_schain_data_to_bytes(self, lifetime, type_of_nodes, name,
)
return data_bytes

@transaction_method(GAS['get_bounty'])
@transaction_method(gas_limit=GAS['get_bounty'])
def get_bounty(self, node_id):
return self.contract.functions.getBounty(node_id)

@transaction_method(GAS['send_verdict'])
@transaction_method(gas_limit=GAS['send_verdict'])
def send_verdict(self, validator, node_id, downtime, latency):
return self.contract.functions.sendVerdict(validator, node_id, downtime,
latency)

@transaction_method(GAS['send_verdicts'])
@transaction_method(gas_limit=GAS['send_verdicts'])
def send_verdicts(self, validator, nodes_ids, downtimes, latencies):
return self.contract.functions.sendVerdicts(validator, nodes_ids,
downtimes, latencies)

@transaction_method(GAS['delete_node'])
@transaction_method(gas_limit=GAS['delete_node'])
def deregister(self, node_id):
return self.contract.functions.deleteNode(node_id)

@transaction_method(GAS['delete_schain'])
@transaction_method(gas_limit=GAS['delete_schain'])
def delete_schain(self, schain_name):
return self.contract.functions.deleteSchain(schain_name)

@transaction_method(GAS['delete_node_by_root'])
@transaction_method(gas_limit=GAS['delete_node_by_root'])
def delete_node_by_root(self, node_id):
return self.contract.functions.deleteNodeByRoot(node_id)
2 changes: 1 addition & 1 deletion skale/contracts/test/time_helpers_with_debug.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
class TimeHelpersWithDebug(BaseContract):
"""Wrapper for TimeHelpersWithDebug.sol functions (internal usage only)"""

@transaction_method(GAS['skip_time'])
@transaction_method(gas_limit=GAS['skip_time'])
def skip_time(self, sec: int) -> TxRes:
"""Skip time on contracts
Expand Down
4 changes: 2 additions & 2 deletions skale/contracts/token.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@


class Token(BaseContract):
@transaction_method(GAS['token_transfer'])
@transaction_method(gas_limit=GAS['token_transfer'])
def transfer(self, address, value):
return self.contract.functions.send(address, value, b'')

def get_balance(self, address):
return self.contract.functions.balanceOf(address).call()

@transaction_method(GAS['token_transfer'])
@transaction_method(gas_limit=GAS['token_transfer'])
def add_authorized(self, address, wallet): # pragma: no cover
return self.contract.functions.addAuthorized(address)
2 changes: 1 addition & 1 deletion skale/dataclasses/current_node_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
class CurrentNodeInfo(NodeInfo):
def __init__(self, node_id, node_name, base_port, bind_ip, ima_mainnet=None,
ima_mp_schain=None, ima_mp_mainnet=None, wallets=None, rotate_after_block=64,
schain_log_level='trace', schain_log_level_config='trace'):
schain_log_level='info', schain_log_level_config='info'):
self.bind_ip = bind_ip
self.schain_log_level = schain_log_level
self.schain_log_level_config = schain_log_level_config
Expand Down
4 changes: 2 additions & 2 deletions skale/schain_config/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ def generate_schain_config(base_config, node_info, schain_info):

def generate_skale_schain_config(skale, schain_name, node_id, base_config=None, ima_mainnet=None,
ima_mp_schain=None, ima_mp_mainnet=None, wallets=None,
rotate_after_block=64, schain_log_level='trace',
schain_log_level_config='trace'):
rotate_after_block=64, schain_log_level='info',
schain_log_level_config='info'):
node = skale.nodes_data.get(node_id)
schain = skale.schains_data.get_by_name(schain_name)

Expand Down
Loading

0 comments on commit ee8b1e6

Please sign in to comment.