Skip to content

Commit

Permalink
Merge pull request #83 from skalenetwork/add-waiting-for-next-block
Browse files Browse the repository at this point in the history
Add waiting for next block
  • Loading branch information
badrogger authored Jan 20, 2020
2 parents 9990647 + 38da66b commit e8d231d
Show file tree
Hide file tree
Showing 13 changed files with 118 additions and 56 deletions.
5 changes: 3 additions & 2 deletions skale/contracts/base_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,16 @@

from web3 import Web3

from skale.utils.web3_utils import TransactionFailedError, wait_receipt
from skale.utils.web3_utils import (TransactionFailedError,
wait_for_receipt_by_blocks)


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'])
receipt = wait_for_receipt_by_blocks(self.skale.web3, res['tx'])
if receipt.get('status') == 1:
return receipt
else:
Expand Down
9 changes: 6 additions & 3 deletions skale/contracts/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ 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'])
tx = post_transaction(self.skale.wallet, op, GAS['set_periods'],
gas_price=self.skale.gas_price)
return {'tx': tx}

def get_reward_period(self):
Expand All @@ -38,7 +39,8 @@ def get_delta_period(self):
@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'])
tx = post_transaction(self.skale.wallet, op, GAS['set_check_time'],
gas_price=self.skale.gas_price)
return {'tx': tx}

def get_check_time(self):
Expand All @@ -47,7 +49,8 @@ def get_check_time(self):
@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'])
tx = post_transaction(self.skale.wallet, op, GAS['set_latency'],
gas_price=self.skale.gas_price)
return {'tx': tx}

def get_latency(self):
Expand Down
22 changes: 17 additions & 5 deletions skale/contracts/dkg.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,43 @@
# 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 DKG(BaseContract):
@transaction_method
def broadcast(self, group_index, node_index,
verification_vector, secret_key_conribution):
op = self.contract.functions.broadcast(group_index, node_index,
verification_vector,
secret_key_conribution)
return post_transaction(self.skale.wallet, op, GAS['dkg_broadcast'])
tx = post_transaction(self.skale.wallet, op, GAS['dkg_broadcast'],
self.skale.gas_price)
return {'tx': tx}

@transaction_method
def response(self, group_index, from_node_index,
secret_number, multiplied_share):
op = self.contract.functions.response(group_index, from_node_index,
secret_number,
multiplied_share)
return post_transaction(self.skale.wallet, op, GAS['dkg_response'])
tx = post_transaction(self.skale.wallet, op, GAS['dkg_response'],
self.skale.gas_price)
return {'tx': tx}

@transaction_method
def allright(self, group_index, from_node_index):
op = self.contract.functions.allright(group_index, from_node_index)
return post_transaction(self.skale.wallet, op, GAS['dkg_allright'])
tx = post_transaction(self.skale.wallet, op, GAS['dkg_allright'],
self.skale.gas_price)
return {'tx': tx}

@transaction_method
def complaint(self, group_index, from_node_index, to_node_index):
op = self.contract.functions.complaint(group_index, from_node_index,
to_node_index)
return post_transaction(self.skale.wallet, op, GAS['dkg_complaint'])
tx = post_transaction(self.skale.wallet, op, GAS['dkg_complaint'],
self.skale.gas_price)
return {'tx': tx}
24 changes: 16 additions & 8 deletions skale/contracts/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ def create_node(self, ip, port, name, public_ip=None):

op = token.contract.functions.send(self.address, NODE_DEPOSIT,
transaction_data)
tx = post_transaction(self.skale.wallet, op, GAS['create_node'])
tx = post_transaction(self.skale.wallet, op, GAS['create_node'],
self.skale.gas_price)
return {'tx': tx, 'nonce': skale_nonce}

def create_node_data_to_bytes(self, ip, public_ip, port, name, pk, nonce):
Expand Down Expand Up @@ -97,7 +98,8 @@ def create_schain(self, lifetime, type_of_nodes, deposit, name):

op = token.contract.functions.send(self.address, deposit,
transaction_data)
tx = post_transaction(self.skale.wallet, op, GAS['create_schain'])
tx = post_transaction(self.skale.wallet, op, GAS['create_schain'],
self.skale.gas_price)
return {'tx': tx, 'nonce': skale_nonce}

def create_schain_data_to_bytes(self, lifetime, type_of_nodes, name,
Expand All @@ -120,37 +122,43 @@ def create_schain_data_to_bytes(self, lifetime, type_of_nodes, name,
@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'])
tx = post_transaction(self.skale.wallet, op, GAS['get_bounty'],
self.skale.gas_price)
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'])
tx = post_transaction(self.skale.wallet, op, GAS['send_verdict'],
self.skale.gas_price)
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'])
tx = post_transaction(self.skale.wallet, op, GAS['send_verdicts'],
self.skale.gas_price)
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'])
tx = post_transaction(self.skale.wallet, op, GAS['delete_node'],
self.skale.gas_price)
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'])
tx = post_transaction(self.skale.wallet, op, GAS['delete_schain'],
self.skale.gas_price)
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'])
tx = post_transaction(self.skale.wallet, op, GAS['delete_node_by_root'],
self.skale.gas_price)
return {'tx': tx}
6 changes: 4 additions & 2 deletions skale/contracts/token.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ 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'])
tx = post_transaction(self.skale.wallet, op, GAS['token_transfer'],
self.skale.gas_price)
return {'tx': tx}

def get_balance(self, address):
Expand All @@ -36,5 +37,6 @@ def get_balance(self, address):
@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'])
tx = post_transaction(self.skale.wallet, op, GAS['token_transfer'],
self.skale.gas_price)
return {'tx': tx}
4 changes: 4 additions & 0 deletions skale/manager_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ def __init__(self, endpoint, abi_filepath, wallet=None):
self.__init_contracts_info()
self.__init_contracts()

@property
def gas_price(self):
return self.web3.eth.gasPrice * 3 // 2

@property
def wallet(self):
if not self._wallet:
Expand Down
18 changes: 11 additions & 7 deletions skale/transactions/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,19 @@
logger = logging.getLogger(__name__)


def build_tx_dict(method, gas_amount, nonce=None):
return method.buildTransaction({
'gas': gas_amount,
def build_tx_dict(method, gas_limit, gas_price=None, nonce=None):
tx_dict_fields = {
'gas': gas_limit,
'nonce': nonce
})
}
if gas_price is not None:
tx_dict_fields.update({'gasPrice': gas_price})

return method.buildTransaction(tx_dict_fields)

def post_transaction(wallet, method, gas_amount, nonce=None):
tx_dict = build_tx_dict(method, gas_amount, nonce)

def post_transaction(wallet, method, gas_limit, gas_price=None, nonce=None):
tx_dict = build_tx_dict(method, gas_limit, gas_price, nonce)
return wallet.sign_and_send(tx_dict)


Expand All @@ -51,7 +55,7 @@ def send_eth(web3, account, amount, wallet):
'to': account,
'from': wallet.address,
'value': amount,
'gasPrice': web3.eth.gasPrice,
'gasPrice': web3.eth.gasPrice * 3 // 2,
'gas': 22000,
'nonce': eth_nonce
}
Expand Down
6 changes: 3 additions & 3 deletions skale/utils/account_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from skale.transactions.tools import send_eth
from skale.utils.constants import LONG_LINE
from skale.wallets import LedgerWallet, Web3Wallet
from skale.utils.web3_utils import check_receipt, wait_receipt
from skale.utils.web3_utils import check_receipt, wait_for_receipt_by_blocks

logger = logging.getLogger(__name__)

Expand All @@ -48,7 +48,7 @@ def send_tokens(skale, sender_wallet, receiver_account, amount,
wei_amount = skale.web3.toWei(amount, 'ether')
res = skale.token.transfer(receiver_account, wei_amount)
if wait_for:
receipt = wait_receipt(skale.web3, res['tx'])
receipt = wait_for_receipt_by_blocks(skale.web3, res['tx'])
check_receipt(receipt)
return receipt
else: # pragma: no cover
Expand All @@ -65,7 +65,7 @@ def send_ether(web3, sender_wallet, receiver_account, amount,
wei_amount = web3.toWei(amount, 'ether')
tx = send_eth(web3, receiver_account, wei_amount, sender_wallet)
if wait_for:
receipt = wait_receipt(web3, tx)
receipt = wait_for_receipt_by_blocks(web3, tx)
check_receipt(receipt)
return receipt
else: # pragma: no cover
Expand Down
15 changes: 15 additions & 0 deletions skale/utils/web3_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,21 @@ def get_eth_nonce(web3, address):
return web3.eth.getTransactionCount(address)


def wait_for_receipt_by_blocks(web3, tx, timeout=3, blocks_to_wait=2):
previous_block = web3.eth.blockNumber
current_block = previous_block
while current_block <= previous_block + blocks_to_wait:
try:
receipt = get_receipt(web3, tx)
except TransactionNotFound:
receipt = None
if receipt is not None:
return receipt
current_block = web3.eth.blockNumber
sleep(timeout)
raise TransactionNotFound(f"Transaction with hash: {tx} not found.")


def wait_receipt(web3, tx, retries=30, timeout=5):
for _ in range(0, retries):
try:
Expand Down
13 changes: 5 additions & 8 deletions tests/contracts/dkg_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@

def test_broadcast(skale):
nonce = skale.web3.eth.getTransactionCount(skale.wallet.address)
gas_price = skale.web3.eth.gasPrice
# gas_price = skale.web3.eth.gasPrice
contract_address = skale.dkg.address
chain_id = skale.web3.eth.chainId
expected_txn = {
'value': 0, 'gasPrice': gas_price, 'chainId': chain_id,
'value': 0, 'gasPrice': skale.gas_price, 'chainId': chain_id,
'gas': 8000000, 'nonce': nonce,
'to': contract_address,
'data': (
Expand All @@ -32,11 +32,10 @@ def test_broadcast(skale):

def test_response(skale):
nonce = skale.web3.eth.getTransactionCount(skale.wallet.address)
gas_price = skale.web3.eth.gasPrice
contract_address = skale.dkg.address
chain_id = skale.web3.eth.chainId
expected_txn = {
'value': 0, 'gasPrice': gas_price, 'chainId': chain_id,
'value': 0, 'gasPrice': skale.gas_price, 'chainId': chain_id,
'gas': 8000000, 'nonce': nonce,
'to': contract_address,
'data': (
Expand All @@ -59,11 +58,10 @@ def test_response(skale):

def test_allright(skale):
nonce = skale.web3.eth.getTransactionCount(skale.wallet.address)
gas_price = skale.web3.eth.gasPrice
contract_address = skale.dkg.address
chain_id = skale.web3.eth.chainId
expected_txn = {
'value': 0, 'gasPrice': gas_price, 'chainId': chain_id,
'value': 0, 'gasPrice': skale.gas_price, 'chainId': chain_id,
'gas': 1000000, 'nonce': nonce,
'to': contract_address,
'data': (
Expand All @@ -83,11 +81,10 @@ def test_allright(skale):

def test_complaint(skale):
nonce = skale.web3.eth.getTransactionCount(skale.wallet.address)
gas_price = skale.web3.eth.gasPrice
contract_address = skale.dkg.address
chain_id = skale.web3.eth.chainId
expected_txn = {
'value': 0, 'gasPrice': gas_price, 'chainId': chain_id,
'value': 0, 'gasPrice': skale.gas_price, 'chainId': chain_id,
'gas': 1000000, 'nonce': nonce,
'to': contract_address,
'data': (
Expand Down
15 changes: 7 additions & 8 deletions tests/contracts/manager_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,10 @@ def test_create_schain_data_to_bytes(skale):
def test_get_bounty(skale):
node_id = 0
nonce = skale.web3.eth.getTransactionCount(skale.wallet.address)
gas_price = skale.web3.eth.gasPrice
contract_address = skale.manager.address
chain_id = skale.web3.eth.chainId
expected_txn = {
'value': 0, 'gasPrice': gas_price, 'chainId': chain_id,
'value': 0, 'gasPrice': skale.gas_price, 'chainId': chain_id,
'gas': GAS['get_bounty'], 'nonce': nonce,
'to': contract_address,
'data': (
Expand All @@ -85,11 +84,10 @@ def test_get_bounty(skale):

def test_send_verdict(skale):
nonce = skale.web3.eth.getTransactionCount(skale.wallet.address)
gas_price = skale.web3.eth.gasPrice
contract_address = skale.manager.address
chain_id = skale.web3.eth.chainId
expected_txn = {
'value': 0, 'gasPrice': gas_price, 'chainId': chain_id,
'value': 0, 'gasPrice': skale.gas_price, 'chainId': chain_id,
'gas': 200000, 'nonce': nonce,
'to': contract_address,
'data': (
Expand All @@ -116,11 +114,10 @@ def test_send_verdict(skale):

def test_send_verdicts(skale):
nonce = skale.web3.eth.getTransactionCount(skale.wallet.address)
gas_price = skale.web3.eth.gasPrice
contract_address = skale.manager.address
chain_id = skale.web3.eth.chainId
expected_txn = {
'value': 0, 'gasPrice': gas_price, 'chainId': chain_id,
'value': 0, 'gasPrice': skale.gas_price, 'chainId': chain_id,
'gas': 500000, 'nonce': nonce,
'to': contract_address,
'data': ('0x25b2114b000000000000000000000000000000000000000000'
Expand Down Expand Up @@ -270,7 +267,9 @@ 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 mock.patch(
'skale.contracts.base_contract.wait_for_receipt_by_blocks',
return_value={'status': 0}
):
with pytest.raises(TransactionFailedError):
skale.manager.create_node(ip, port, name, wait_for=True)
Loading

0 comments on commit e8d231d

Please sign in to comment.