diff --git a/raiden/constants.py b/raiden/constants.py index e394ecc77e..808c6db0cd 100644 --- a/raiden/constants.py +++ b/raiden/constants.py @@ -1,3 +1,4 @@ +import math from enum import Enum from eth_utils import to_checksum_address @@ -31,12 +32,18 @@ class EthClient(Enum): START_QUERY_BLOCK_KEY = 'DefaultStartBlock' SNAPSHOT_STATE_CHANGES_COUNT = 500 +# An arbitrary limit for transaction size in Raiden, added in PR #1990 +TRANSACTION_GAS_LIMIT_UPPER_BOUND = int(0.4 * 3_141_592) + +# Used to add a 30% security margin to gas estimations in case the calculations are off +GAS_FACTOR = 1.3 + # The more pending transfers there are, the more computationally complex # it becomes to unlock them. Lest an unlocking operation fails because # not enough gas is available, we define a gas limit for unlock calls # and limit the number of pending transfers per channel so it is not # exceeded. The limit is inclusive. -TRANSACTION_GAS_LIMIT = int(0.4 * 3141592) +UNLOCK_TX_GAS_LIMIT = TRANSACTION_GAS_LIMIT_UPPER_BOUND MAXIMUM_PENDING_TRANSFERS = 160 @@ -44,3 +51,8 @@ class Environment(Enum): """Environment configurations that can be chosen on the command line.""" PRODUCTION = 'production' DEVELOPMENT = 'development' + + +GAS_REQUIRED_FOR_CREATE_ERC20_TOKEN_NETWORK = 3_234_716 +GAS_REQUIRED_PER_SECRET_IN_BATCH = math.ceil(UNLOCK_TX_GAS_LIMIT / MAXIMUM_PENDING_TRANSFERS) +GAS_LIMIT_FOR_TOKEN_CONTRACT_CALL = 100_000 diff --git a/raiden/network/proxies/discovery.py b/raiden/network/proxies/discovery.py index 0b05e40e6d..5d05b754f0 100644 --- a/raiden/network/proxies/discovery.py +++ b/raiden/network/proxies/discovery.py @@ -7,8 +7,11 @@ from raiden.network.rpc.client import check_address_has_code from raiden.network.rpc.smartcontract_proxy import ContractProxy from raiden.network.rpc.transactions import check_transaction_threw -from raiden.utils import pex, privatekey_to_address -from raiden_contracts.constants import CONTRACT_ENDPOINT_REGISTRY +from raiden.utils import pex, privatekey_to_address, safe_gas_limit +from raiden_contracts.constants import ( + CONTRACT_ENDPOINT_REGISTRY, + GAS_REQUIRED_FOR_ENDPOINT_REGISTER, +) from raiden_contracts.contract_manager import ContractManager log = structlog.get_logger(__name__) # pylint: disable=invalid-name @@ -63,6 +66,7 @@ def register_endpoint(self, node_address, endpoint): transaction_hash = self.proxy.transact( 'registerEndpoint', + safe_gas_limit(GAS_REQUIRED_FOR_ENDPOINT_REGISTER), endpoint, ) diff --git a/raiden/network/proxies/secret_registry.py b/raiden/network/proxies/secret_registry.py index a175517ba5..14104fac26 100644 --- a/raiden/network/proxies/secret_registry.py +++ b/raiden/network/proxies/secret_registry.py @@ -4,12 +4,12 @@ from eth_utils import encode_hex, event_abi_to_log_topic, is_binary_address, to_normalized_address from gevent.event import AsyncResult -from raiden.constants import GENESIS_BLOCK_NUMBER +from raiden.constants import GAS_REQUIRED_PER_SECRET_IN_BATCH, GENESIS_BLOCK_NUMBER from raiden.exceptions import InvalidAddress, TransactionThrew from raiden.network.proxies.utils import compare_contract_versions from raiden.network.rpc.client import StatelessFilter, check_address_has_code from raiden.network.rpc.transactions import check_transaction_threw -from raiden.utils import pex, privatekey_to_address, sha3, typing +from raiden.utils import pex, privatekey_to_address, safe_gas_limit, sha3, typing from raiden_contracts.constants import CONTRACT_SECRET_REGISTRY, EVENT_SECRET_REVEALED from raiden_contracts.contract_manager import ContractManager @@ -98,7 +98,9 @@ def register_secret_batch(self, secrets: List[typing.Secret]): self.open_secret_transactions.pop(secret, None) def _register_secret_batch(self, secrets): - transaction_hash = self.proxy.transact('registerSecretBatch', secrets) + gas_limit = self.proxy.estimate_gas('registerSecretBatch', secrets) + gas_limit = safe_gas_limit(gas_limit, len(secrets) * GAS_REQUIRED_PER_SECRET_IN_BATCH) + transaction_hash = self.proxy.transact('registerSecretBatch', gas_limit, secrets) self.client.poll(transaction_hash) receipt_or_none = check_transaction_threw(self.client, transaction_hash) diff --git a/raiden/network/proxies/token.py b/raiden/network/proxies/token.py index 96e8a3f12d..47b2acbc9b 100644 --- a/raiden/network/proxies/token.py +++ b/raiden/network/proxies/token.py @@ -1,11 +1,12 @@ import structlog from eth_utils import is_binary_address, to_checksum_address, to_normalized_address +from raiden.constants import GAS_LIMIT_FOR_TOKEN_CONTRACT_CALL from raiden.exceptions import TransactionThrew from raiden.network.rpc.client import check_address_has_code from raiden.network.rpc.smartcontract_proxy import ContractProxy from raiden.network.rpc.transactions import check_transaction_threw -from raiden.utils import pex, privatekey_to_address +from raiden.utils import pex, privatekey_to_address, safe_gas_limit from raiden_contracts.constants import CONTRACT_HUMAN_STANDARD_TOKEN from raiden_contracts.contract_manager import ContractManager @@ -58,8 +59,15 @@ def approve(self, allowed_address, allowance): } log.debug('approve called', **log_details) + startgas = self.proxy.estimate_gas( + 'approve', + to_checksum_address(allowed_address), + allowance, + ) + transaction_hash = self.proxy.transact( 'approve', + safe_gas_limit(startgas), to_checksum_address(allowed_address), allowance, ) @@ -122,8 +130,10 @@ def transfer(self, to_address, amount): } log.debug('transfer called', **log_details) + startgas = GAS_LIMIT_FOR_TOKEN_CONTRACT_CALL transaction_hash = self.proxy.transact( 'transfer', + safe_gas_limit(startgas), to_checksum_address(to_address), amount, ) diff --git a/raiden/network/proxies/token_network.py b/raiden/network/proxies/token_network.py index d606b4db79..bd7f08c614 100644 --- a/raiden/network/proxies/token_network.py +++ b/raiden/network/proxies/token_network.py @@ -12,7 +12,7 @@ from gevent.event import AsyncResult from gevent.lock import RLock, Semaphore -from raiden.constants import GENESIS_BLOCK_NUMBER +from raiden.constants import GENESIS_BLOCK_NUMBER, UNLOCK_TX_GAS_LIMIT from raiden.exceptions import ( ChannelOutdatedError, DepositMismatch, @@ -30,9 +30,14 @@ from raiden.network.rpc.client import StatelessFilter, check_address_has_code from raiden.network.rpc.transactions import check_transaction_threw from raiden.transfer.balance_proof import pack_balance_proof -from raiden.utils import pex, privatekey_to_address, typing +from raiden.utils import pex, privatekey_to_address, safe_gas_limit, typing from raiden_contracts.constants import ( CONTRACT_TOKEN_NETWORK, + GAS_REQUIRED_FOR_CLOSE_CHANNEL, + GAS_REQUIRED_FOR_OPEN_CHANNEL, + GAS_REQUIRED_FOR_SET_TOTAL_DEPOSIT, + GAS_REQUIRED_FOR_SETTLE_CHANNEL, + GAS_REQUIRED_FOR_UPDATE_BALANCE_PROOF, ChannelInfoIndex, ChannelState, ParticipantInfoIndex, @@ -195,8 +200,17 @@ def _new_netting_channel(self, partner: typing.Address, settle_timeout: int): if self.channel_exists_and_not_settled(self.node_address, partner): raise DuplicatedChannelError('Channel with given partner address already exists') + gas_limit = self.proxy.estimate_gas( + 'openChannel', + self.node_address, + partner, + settle_timeout, + ) + gas_limit = safe_gas_limit(gas_limit, GAS_REQUIRED_FOR_OPEN_CHANNEL) + transaction_hash = self.proxy.transact( 'openChannel', + gas_limit, self.node_address, partner, settle_timeout, @@ -589,8 +603,18 @@ def set_total_deposit( # making the second deposit fail. token.approve(self.address, amount_to_deposit) + gas_limit = self.proxy.estimate_gas( + 'setTotalDeposit', + channel_identifier, + self.node_address, + total_deposit, + partner, + ) + gas_limit = safe_gas_limit(gas_limit, GAS_REQUIRED_FOR_SET_TOTAL_DEPOSIT) + transaction_hash = self.proxy.transact( 'setTotalDeposit', + gas_limit, channel_identifier, self.node_address, total_deposit, @@ -601,6 +625,12 @@ def set_total_deposit( receipt_or_none = check_transaction_threw(self.client, transaction_hash) if receipt_or_none: + latest_deposit = self.detail_participant( + channel_identifier, + self.node_address, + partner, + ).deposit + if token.allowance(self.node_address, self.address) < amount_to_deposit: log_msg = ( 'setTotalDeposit failed. The allowance is insufficient, ' @@ -609,6 +639,8 @@ def set_total_deposit( ) elif token.balance_of(self.node_address) < amount_to_deposit: log_msg = 'setTotalDeposit failed. The address doesnt have funds' + elif latest_deposit < total_deposit: + log_msg = 'setTotalDeposit failed. The tokens were not transferred' else: log_msg = 'setTotalDeposit failed' @@ -668,6 +700,7 @@ def close( with self.channel_operations_lock[partner]: transaction_hash = self.proxy.transact( 'closeChannel', + safe_gas_limit(GAS_REQUIRED_FOR_CLOSE_CHANNEL), channel_identifier, partner, balance_hash, @@ -771,6 +804,7 @@ def update_transfer( transaction_hash = self.proxy.transact( 'updateNonClosingBalanceProof', + safe_gas_limit(GAS_REQUIRED_FOR_UPDATE_BALANCE_PROOF), channel_identifier, partner, self.node_address, @@ -856,8 +890,13 @@ def withdraw( raise ValueError(msg) with self.channel_operations_lock[partner]: + # gaslimit below must be defined + raise NotImplementedError('feature temporarily disabled') + + gas_limit = None transaction_hash = self.proxy.transact( 'setTotalWithdraw', + gas_limit, channel_identifier, self.node_address, total_withdraw, @@ -902,8 +941,18 @@ def unlock( leaves_packed = b''.join(lock.encoded for lock in merkle_tree_leaves) + gas_limit = self.proxy.estimate_gas( + 'unlock', + channel_identifier, + self.node_address, + partner, + leaves_packed, + ) + gas_limit = safe_gas_limit(gas_limit, UNLOCK_TX_GAS_LIMIT) + transaction_hash = self.proxy.transact( 'unlock', + gas_limit, channel_identifier, self.node_address, partner, @@ -974,8 +1023,23 @@ def settle( our_bp_is_larger = our_maximum > partner_maximum if our_bp_is_larger: + gas_limit = self.proxy.estimate_gas( + 'settleChannel', + channel_identifier, + partner, + partner_transferred_amount, + partner_locked_amount, + partner_locksroot, + self.node_address, + transferred_amount, + locked_amount, + locksroot, + ) + gas_limit = safe_gas_limit(gas_limit, GAS_REQUIRED_FOR_SETTLE_CHANNEL) + transaction_hash = self.proxy.transact( 'settleChannel', + gas_limit, channel_identifier, partner, partner_transferred_amount, @@ -987,8 +1051,23 @@ def settle( locksroot, ) else: + gas_limit = self.proxy.estimate_gas( + 'settleChannel', + channel_identifier, + self.node_address, + transferred_amount, + locked_amount, + locksroot, + partner, + partner_transferred_amount, + partner_locked_amount, + partner_locksroot, + ) + gas_limit = safe_gas_limit(gas_limit, GAS_REQUIRED_FOR_SETTLE_CHANNEL) + transaction_hash = self.proxy.transact( 'settleChannel', + gas_limit, channel_identifier, self.node_address, transferred_amount, diff --git a/raiden/network/proxies/token_network_registry.py b/raiden/network/proxies/token_network_registry.py index a101d98505..03ad27b581 100644 --- a/raiden/network/proxies/token_network_registry.py +++ b/raiden/network/proxies/token_network_registry.py @@ -11,12 +11,16 @@ to_normalized_address, ) -from raiden.constants import GENESIS_BLOCK_NUMBER, NULL_ADDRESS +from raiden.constants import ( + GAS_REQUIRED_FOR_CREATE_ERC20_TOKEN_NETWORK, + GENESIS_BLOCK_NUMBER, + NULL_ADDRESS, +) from raiden.exceptions import InvalidAddress, RaidenRecoverableError, TransactionThrew from raiden.network.proxies.utils import compare_contract_versions from raiden.network.rpc.client import StatelessFilter, check_address_has_code from raiden.network.rpc.transactions import check_transaction_threw -from raiden.utils import pex, privatekey_to_address, typing +from raiden.utils import pex, privatekey_to_address, safe_gas_limit, typing from raiden_contracts.constants import CONTRACT_TOKEN_NETWORK_REGISTRY, EVENT_TOKEN_NETWORK_CREATED from raiden_contracts.contract_manager import ContractManager @@ -83,6 +87,7 @@ def add_token(self, token_address: typing.TokenAddress): transaction_hash = self.proxy.transact( 'createERC20TokenNetwork', + safe_gas_limit(GAS_REQUIRED_FOR_CREATE_ERC20_TOKEN_NETWORK), token_address, ) diff --git a/raiden/network/rpc/client.py b/raiden/network/rpc/client.py index 79a5bf500a..bd33faaeed 100644 --- a/raiden/network/rpc/client.py +++ b/raiden/network/rpc/client.py @@ -257,10 +257,6 @@ def balance(self, account: typing.Address): """ Return the balance of the account of given address. """ return self.web3.eth.getBalance(to_checksum_address(account), 'pending') - def gaslimit(self, location='latest') -> int: - gas_limit = self.web3.eth.getBlock(location)['gasLimit'] - return gas_limit * 8 // 10 - def gas_price(self) -> int: # generateGasPrice takes the transaction to be send as an optional argument # but both strategies that we are using (time-based and rpc-based) don't make @@ -268,11 +264,6 @@ def gas_price(self) -> int: # This needs to be reevaluated if we use different gas price strategies return int(self.web3.eth.generateGasPrice()) - def check_startgas(self, startgas): - if not startgas: - return self.gaslimit() - return startgas - def new_contract_proxy(self, contract_interface, contract_address: typing.Address): """ Return a proxy for interacting with a smart contract. @@ -368,8 +359,10 @@ def deploy_solidity_contract( dependency_contract['bin'] = bytecode + gas_limit = self.web3.eth.getBlock('latest')['gasLimit'] * 8 // 10 transaction_hash = self.send_transaction( to=typing.Address(b''), + startgas=gas_limit, data=bytecode, ) @@ -427,9 +420,9 @@ def deploy_solidity_contract( def send_transaction( self, to: typing.Address, + startgas: int, value: int = 0, data: bytes = b'', - startgas: int = None, ) -> bytes: """ Helper to send signed messages. @@ -442,7 +435,6 @@ def send_transaction( with self._nonce_lock: nonce = self._available_nonce - startgas = self.check_startgas(startgas) gas_price = self.gas_price() transaction = { diff --git a/raiden/network/rpc/smartcontract_proxy.py b/raiden/network/rpc/smartcontract_proxy.py index 4ca9260b42..0af10744e6 100644 --- a/raiden/network/rpc/smartcontract_proxy.py +++ b/raiden/network/rpc/smartcontract_proxy.py @@ -66,12 +66,13 @@ def __init__( self.jsonrpc_client = jsonrpc_client self.contract = contract - def transact(self, function_name: str, *args, **kargs): + def transact(self, function_name: str, startgas: int, *args, **kargs): data = ContractProxy.get_transaction_data(self.contract.abi, function_name, args) try: txhash = self.jsonrpc_client.send_transaction( to=self.contract.address, + startgas=startgas, value=kargs.pop('value', 0), data=decode_hex(data), **kargs, diff --git a/raiden/tests/integration/rpc/test_assumptions.py b/raiden/tests/integration/rpc/test_assumptions.py index 6a9f677b29..cc5a5055ba 100644 --- a/raiden/tests/integration/rpc/test_assumptions.py +++ b/raiden/tests/integration/rpc/test_assumptions.py @@ -6,6 +6,7 @@ from raiden.exceptions import ReplacementTransactionUnderpriced, TransactionAlreadyPending from raiden.network.rpc.client import JSONRPCClient from raiden.network.rpc.transactions import check_transaction_threw +from raiden.utils import safe_gas_limit from raiden.utils.solc import compile_files_cwd # pylint: disable=unused-argument,protected-access @@ -131,11 +132,11 @@ def test_duplicated_transaction_same_gas_price_raises(deploy_client): contract_proxy.contract_address, ) - gas = contract_proxy.estimate_gas('ret') * 2 + startgas = safe_gas_limit(contract_proxy.estimate_gas('ret')) with pytest.raises(TransactionAlreadyPending): - second_proxy.transact('ret', startgas=gas) - contract_proxy.transact('ret', startgas=gas) + second_proxy.transact('ret', startgas) + contract_proxy.transact('ret', startgas) def test_duplicated_transaction_different_gas_price_raises(deploy_client): @@ -157,11 +158,11 @@ def test_duplicated_transaction_different_gas_price_raises(deploy_client): contract_proxy.contract_address, ) - gas = contract_proxy.estimate_gas('ret') * 2 + startgas = safe_gas_limit(contract_proxy.estimate_gas('ret')) with pytest.raises(ReplacementTransactionUnderpriced): - second_proxy.transact('ret', startgas=gas) - contract_proxy.transact('ret', startgas=gas) + second_proxy.transact('ret', startgas) + contract_proxy.transact('ret', startgas) def test_transact_opcode(deploy_client): @@ -171,9 +172,9 @@ def test_transact_opcode(deploy_client): address = contract_proxy.contract_address assert len(deploy_client.web3.eth.getCode(to_checksum_address(address))) > 0 - gas = contract_proxy.estimate_gas('ret') * 2 + startgas = contract_proxy.estimate_gas('ret') * 2 - transaction = contract_proxy.transact('ret', startgas=gas) + transaction = contract_proxy.transact('ret', startgas) deploy_client.poll(transaction) assert check_transaction_threw(deploy_client, transaction) is None, 'must be empty' @@ -186,9 +187,10 @@ def test_transact_throws_opcode(deploy_client): address = contract_proxy.contract_address assert len(deploy_client.web3.eth.getCode(to_checksum_address(address))) > 0 - gas = deploy_client.gaslimit() + # the gas estimation returns 0 here, so hardcode a value + startgas = safe_gas_limit(22_000) - transaction = contract_proxy.transact('fail', startgas=gas) + transaction = contract_proxy.transact('fail', startgas) deploy_client.poll(transaction) assert check_transaction_threw(deploy_client, transaction), 'must not be empty' @@ -201,9 +203,10 @@ def test_transact_opcode_oog(deploy_client): address = contract_proxy.contract_address assert len(deploy_client.web3.eth.getCode(to_checksum_address(address))) > 0 - gas = min(contract_proxy.estimate_gas('loop', 1000) // 2, deploy_client.gaslimit()) + # divide the estimate by 2 to run into out-of-gas + startgas = safe_gas_limit(contract_proxy.estimate_gas('loop', 1000)) // 2 - transaction = contract_proxy.transact('loop', 1000, startgas=gas) + transaction = contract_proxy.transact('loop', startgas, 1000) deploy_client.poll(transaction) assert check_transaction_threw(deploy_client, transaction), 'must not be empty' @@ -214,10 +217,10 @@ def test_filter_start_block_inclusive(deploy_client): contract_proxy = deploy_rpc_test_contract(deploy_client) # call the create event function twice and wait for confirmation each time - gas = contract_proxy.estimate_gas('createEvent', 1) * 2 - transaction_1 = contract_proxy.transact('createEvent', 1, startgas=gas) + startgas = safe_gas_limit(contract_proxy.estimate_gas('createEvent', 1)) + transaction_1 = contract_proxy.transact('createEvent', startgas, 1) deploy_client.poll(transaction_1) - transaction_2 = contract_proxy.transact('createEvent', 2, startgas=gas) + transaction_2 = contract_proxy.transact('createEvent', startgas, 2) deploy_client.poll(transaction_2) result_1 = deploy_client.get_filter_events(contract_proxy.contract_address) @@ -246,10 +249,10 @@ def test_filter_end_block_inclusive(deploy_client): contract_proxy = deploy_rpc_test_contract(deploy_client) # call the create event function twice and wait for confirmation each time - gas = contract_proxy.estimate_gas('createEvent', 1) * 2 - transaction_1 = contract_proxy.transact('createEvent', 1, startgas=gas) + startgas = safe_gas_limit(contract_proxy.estimate_gas('createEvent', 1)) + transaction_1 = contract_proxy.transact('createEvent', startgas, 1) deploy_client.poll(transaction_1) - transaction_2 = contract_proxy.transact('createEvent', 2, startgas=gas) + transaction_2 = contract_proxy.transact('createEvent', startgas, 2) deploy_client.poll(transaction_2) result_1 = deploy_client.get_filter_events(contract_proxy.contract_address) diff --git a/raiden/tests/integration/test_endpointregistry.py b/raiden/tests/integration/test_endpointregistry.py index 24f3456a71..ea63825f4b 100644 --- a/raiden/tests/integration/test_endpointregistry.py +++ b/raiden/tests/integration/test_endpointregistry.py @@ -4,7 +4,7 @@ from raiden.network.discovery import ContractDiscovery from raiden.tests.utils.factories import make_address from raiden.tests.utils.smartcontracts import deploy_contract_web3 -from raiden.utils import host_port_to_endpoint, privatekey_to_address +from raiden.utils import host_port_to_endpoint, privatekey_to_address, safe_gas_limit from raiden_contracts.constants import ( CONTRACT_ENDPOINT_REGISTRY, GAS_REQUIRED_FOR_ENDPOINT_REGISTER, @@ -53,8 +53,13 @@ def test_endpointregistry_gas(endpoint_discovery_services): discovery_proxy = contract_discovery.discovery_proxy endpoint = host_port_to_endpoint('127.0.0.1', 44444) - transaction_hash = discovery_proxy.proxy.transact('registerEndpoint', endpoint) + transaction_hash = discovery_proxy.proxy.transact( + 'registerEndpoint', + safe_gas_limit(GAS_REQUIRED_FOR_ENDPOINT_REGISTER), + endpoint, + ) discovery_proxy.client.poll(transaction_hash) receipt = discovery_proxy.client.get_transaction_receipt(transaction_hash) - assert receipt['gasUsed'] <= GAS_REQUIRED_FOR_ENDPOINT_REGISTER + msg = 'the transaction failed, check if it was because of the gas being too low' + assert receipt['status'] != 0, msg diff --git a/raiden/utils/__init__.py b/raiden/utils/__init__.py index 81947be62e..12d2458b5c 100644 --- a/raiden/utils/__init__.py +++ b/raiden/utils/__init__.py @@ -261,3 +261,13 @@ def optional_address_to_string(address: typing.Address = None) -> typing.Optiona return None return to_checksum_address(address) + + +def safe_gas_limit(*estimates) -> int: + """ Calculates a safe gas limit for a number of estimates. + + Even though it's not documented, it does happen that estimate_gas returns `None`. + This function takes care of this and adds a security margin as well. + """ + calculated_limit = max(gas or 0 for gas in estimates) + return int(calculated_limit * constants.GAS_FACTOR) diff --git a/raiden/utils/gas_reserve.py b/raiden/utils/gas_reserve.py index 367a28fd00..78056e6037 100644 --- a/raiden/utils/gas_reserve.py +++ b/raiden/utils/gas_reserve.py @@ -1,6 +1,6 @@ from typing import Tuple -from raiden.constants import TRANSACTION_GAS_LIMIT +from raiden.constants import UNLOCK_TX_GAS_LIMIT from raiden.transfer import views from raiden_contracts.constants import ( GAS_REQUIRED_FOR_CLOSE_CHANNEL, @@ -10,7 +10,7 @@ ) GAS_REQUIRED_FOR_CHANNEL_LIFECYCLE_AFTER_SETTLE = ( - TRANSACTION_GAS_LIMIT + UNLOCK_TX_GAS_LIMIT ) GAS_REQUIRED_FOR_CHANNEL_LIFECYCLE_AFTER_CLOSE = ( GAS_REQUIRED_FOR_SETTLE_CHANNEL + GAS_REQUIRED_FOR_CHANNEL_LIFECYCLE_AFTER_SETTLE diff --git a/tools/scenario-player/scenario_player/runner.py b/tools/scenario-player/scenario_player/runner.py index 21422791dd..ebea2e83be 100644 --- a/tools/scenario-player/scenario_player/runner.py +++ b/tools/scenario-player/scenario_player/runner.py @@ -13,6 +13,7 @@ from web3 import HTTPProvider, Web3 from raiden.accounts import Account +from raiden.constants import GAS_LIMIT_FOR_TOKEN_CONTRACT_CALL from raiden.network.rpc.client import JSONRPCClient from scenario_player.exceptions import NodesUnreachableError, ScenarioError, TokenRegistrationError from scenario_player.utils import ( @@ -228,8 +229,9 @@ def run_scenario(self): balance = token_ctr.contract.functions.balanceOf(address).call() if balance < token_balance_min: mint_amount = token_balance_fund - balance + startgas = GAS_LIMIT_FOR_TOKEN_CONTRACT_CALL log.debug("Minting tokens for", address=address, amount=mint_amount) - mint_tx.append(token_ctr.transact('mintFor', mint_amount, address)) + mint_tx.append(token_ctr.transact('mintFor', startgas, mint_amount, address)) elif balance > token_balance_min: log.warning("Node is overfunded", address=address, balance=balance) diff --git a/tools/transfer_eth.py b/tools/transfer_eth.py index f26348eb39..8629d56ca0 100755 --- a/tools/transfer_eth.py +++ b/tools/transfer_eth.py @@ -44,7 +44,11 @@ def main(keystore_file, password, rpc_url, eth_amount, targets_file): print("Sending {} eth to:".format(eth_amount)) for target in targets: print(" - {}".format(target)) - client.send_transaction(to=target, value=eth_amount * WEI_TO_ETH) + client.send_transaction( + to=target, + startgas=21000, + value=eth_amount * WEI_TO_ETH, + ) if __name__ == "__main__":