def test_check_successful_tx_with_status_zero() -> None: web3_mock = Mock() web3_mock.eth.getTransactionReceipt.return_value = {"blockNumber": 300, "status": 0} txid = "abcdef" with pytest.raises(ValueError): check_successful_tx(web3=web3_mock, txid=txid) web3_mock.eth.getTransactionReceipt.assert_called_with(txid) web3_mock.eth.getTransaction.assert_called_with(txid)
def test_check_successful_tx_with_nonexistent_status() -> None: """ check_successful_tx() with a receipt without status field should raise a KeyError """ web3_mock = Mock() web3_mock.eth.getTransactionReceipt.return_value = {"blockNumber": 300} txid = "abcdef" with pytest.raises(KeyError): check_successful_tx(web3=web3_mock, txid=txid) web3_mock.eth.getTransactionReceipt.assert_called_with(txid) web3_mock.eth.getTransaction.assert_called_with(txid)
def deprecation_test( ctx, private_key, rpc_provider, wait, gas_price, gas_limit, ): """ Turn on the deprecation switch and see channel opening fails """ setup_ctx(ctx, 'limited', private_key, rpc_provider, wait, gas_price, gas_limit) deployer = ctx.obj['deployer'] # We deploy the Raiden Network contracts and register a token network token_amount = MAX_ETH_CHANNEL_PARTICIPANT * 6 channel_participant_deposit_limit = MAX_ETH_CHANNEL_PARTICIPANT token_network_deposit_limit = MAX_ETH_TOKEN_NETWORK ( _, token_network, _, ) = deprecation_test_setup( deployer, token_amount, channel_participant_deposit_limit, token_network_deposit_limit, ) log.info('Checking that channels can be opened and deposits can be made.') # Check that we can open channels and deposit on behalf of A and B # Some arbitrary Ethereum addresses A = '0x6AA63296FA94975017244769F00F0c64DB7d7115' B = '0xc9a4fad99B6d7D3e48D18d2585470cd8f27FA61e' channel_identifier = open_and_deposit(A, B, token_network, deployer) log.info('Seding transaction to activate the deprecation switch.') # Activate deprecation switch assert token_network.functions.safety_deprecation_switch().call() is False txhash = token_network.functions.deprecate().transact( deployer.transaction, ) log.debug(f'Deprecation txHash={encode_hex(txhash)}') check_successful_tx(deployer.web3, txhash, deployer.wait) assert token_network.functions.safety_deprecation_switch().call() is True log.info( 'Checking that channels cannot be opened anymore and no more deposits are allowed.' ) # Check that we cannot open more channels or deposit C = '0x5a23cedB607684118ccf7906dF3e24Efd2964719' D = '0x3827B9cDc68f061aa614F1b97E23664ef3b9220A' open_and_deposit(C, D, token_network, deployer, channel_identifier, False) log.info('Deprecation switch test OK.')
def test_check_successful_tx_with_status_zero(): web3_mock = Mock() web3_mock.eth.getTransactionReceipt.return_value = { 'blockNumber': 300, 'status': 0 } txid = 'abcdef' with pytest.raises(ValueError): check_successful_tx(web3=web3_mock, txid=txid) web3_mock.eth.getTransactionReceipt.assert_called_with(txid) web3_mock.eth.getTransaction.assert_called_with(txid)
def test_check_successful_tx_with_gas_completely_used(): web3_mock = Mock() gas = 30000 web3_mock.eth.getTransactionReceipt.return_value = { 'blockNumber': 300, 'status': 1, 'gasUsed': gas, } web3_mock.eth.getTransaction.return_value = {'gas': gas} txid = 'abcdef' with pytest.raises(ValueError): check_successful_tx(web3=web3_mock, txid=txid) web3_mock.eth.getTransactionReceipt.assert_called_with(txid) web3_mock.eth.getTransaction.assert_called_with(txid)
def test_check_successful_tx_with_gas_completely_used() -> None: web3_mock = Mock() gas = 30000 web3_mock.eth.getTransactionReceipt.return_value = { "blockNumber": 300, "status": 1, "gasUsed": gas, } web3_mock.eth.getTransaction.return_value = {"gas": gas} txid = "abcdef" with pytest.raises(ValueError): check_successful_tx(web3=web3_mock, txid=txid) web3_mock.eth.getTransactionReceipt.assert_called_with(txid) web3_mock.eth.getTransaction.assert_called_with(txid)
def f(initial_amount: int, decimals: int, token_name: str, token_symbol: str) -> Contract: token_contract = deploy_token_contract(initial_amount, decimals, token_name, token_symbol) txid = call_and_transact( token_network_registry_contract.functions.createERC20TokenNetwork( token_contract.address, channel_participant_deposit_limit, token_network_deposit_limit, ), {"from": DEPLOYER_ADDRESS}, ) (tx_receipt, _) = check_successful_tx(web3, txid) assert len(tx_receipt["logs"]) == 1 event_abi = contracts_manager.get_event_abi( CONTRACT_TOKEN_NETWORK_REGISTRY, EVENT_TOKEN_NETWORK_CREATED) decoded_event = get_event_data(event_abi, tx_receipt["logs"][0]) assert decoded_event is not None assert is_address(decoded_event["args"]["token_address"]) assert is_address(decoded_event["args"]["token_network_address"]) token_network_address = decoded_event["args"]["token_network_address"] token_network_abi = contracts_manager.get_contract_abi( CONTRACT_TOKEN_NETWORK) return web3.eth.contract(abi=token_network_abi, address=token_network_address)
def deploy(self, contract_name: str, args: Optional[List] = None) -> Dict: if args is None: args = list() contract_interface: CompiledContract = self.contract_manager.get_contract(contract_name) # Instantiate and deploy contract contract = self.web3.eth.contract( abi=contract_interface["abi"], bytecode=contract_interface["bin"] ) # Get transaction hash from deployed contract txhash = self.send_deployment_transaction(contract=contract, args=args) # Get tx receipt to get contract address LOG.debug( f"Deploying {contract_name} txHash={encode_hex(txhash)}, " f"contracts version {self.contract_manager.contracts_version}" ) (receipt, tx) = check_successful_tx(web3=self.web3, txid=txhash, timeout=self.wait) if not receipt["contractAddress"]: # happens with Parity receipt = dict(receipt) receipt["contractAddress"] = tx["creates"] LOG.info( "{0} address: {1}. Gas used: {2}".format( contract_name, receipt["contractAddress"], receipt["gasUsed"] ) ) return receipt
def transact(self, contract_method: ContractFunction) -> TxReceipt: """A wrapper around to_be_called.transact() that waits until the transaction succeeds.""" txhash = contract_method.transact(self.transaction) LOG.debug(f"Sending txHash={encode_hex(txhash)}") receipt, _ = check_successful_tx(web3=self.web3, txid=txhash, timeout=self.wait) return receipt
def test_check_successful_tx_successful_case() -> None: web3_mock = Mock() gas = 30000 receipt = {"blockNumber": 300, "status": 1, "gasUsed": gas - 10} web3_mock.eth.getTransactionReceipt.return_value = receipt txinfo = {"gas": gas} web3_mock.eth.getTransaction.return_value = txinfo txid = "abcdef" assert check_successful_tx(web3=web3_mock, txid=txid) == (receipt, txinfo) web3_mock.eth.getTransactionReceipt.assert_called_with(txid) web3_mock.eth.getTransaction.assert_called_with(txid)
def test_check_successful_tx_successful_case() -> None: web3_mock = Mock() gas = 30000 receipt = TxReceipt({"blockNumber": 300, "status": 1, "gasUsed": gas - 10}) # type: ignore web3_mock.eth.get_transaction_receipt.return_value = receipt txinfo = TxData({"gas": Wei(gas)}) web3_mock.eth.get_transaction.return_value = txinfo txid = HexBytes("abcdef") assert check_successful_tx(web3=web3_mock, txid=txid) == (receipt, txinfo) web3_mock.eth.get_transaction_receipt.assert_called_with(txid) web3_mock.eth.get_transaction.assert_called_with(txid)
def mint_tokens(self, token_address: ChecksumAddress, amount: int) -> TxReceipt: token_address = to_checksum_address(token_address) assert self.is_valid_contract( token_address ), "The custom token contract does not seem to exist on this address" token_contract = ContractManager(contracts_precompiled_path()).get_contract( CONTRACT_CUSTOM_TOKEN ) token_proxy = self.web3.eth.contract(address=token_address, abi=token_contract["abi"]) txhash = token_proxy.functions.mint(amount).transact({"from": self.owner}) receipt, _ = check_successful_tx(web3=self.web3, txid=txhash, timeout=self.wait) return receipt
def register_token_network( web3: Web3, caller: str, token_registry_abi: Dict, token_registry_address: str, token_registry_version: str, token_address: str, channel_participant_deposit_limit: int, token_network_deposit_limit: int, wait=10, gas_limit=4000000, gas_price=10, ): """Register token with a TokenNetworkRegistry contract.""" token_network_registry = web3.eth.contract( abi=token_registry_abi, address=token_registry_address, ) assert token_network_registry.functions.contract_version().call() == token_registry_version, \ f'got {token_network_registry.functions.contract_version().call()},' \ f'expected {token_registry_version}' txhash = token_network_registry.functions.createERC20TokenNetwork( token_address, channel_participant_deposit_limit, token_network_deposit_limit, ).transact( { 'from': caller, 'gas': gas_limit, 'gasPrice': gas_price * denoms.gwei, # pylint: disable=E1101 }, ) LOG.debug( 'calling createERC20TokenNetwork(%s) txHash=%s' % ( token_address, encode_hex(txhash), ), ) (receipt, _) = check_successful_tx(web3=web3, txid=txhash, timeout=wait) token_network_address = token_network_registry.functions.token_to_token_networks( token_address, ).call() token_network_address = to_checksum_address(token_network_address) print( 'TokenNetwork address: {0} Gas used: {1}'.format( token_network_address, receipt['gasUsed'], ), ) return token_network_address
def test_check_successful_tx_successful_case(): web3_mock = Mock() gas = 30000 receipt = { 'blockNumber': 300, 'status': 1, 'gasUsed': gas - 10, } web3_mock.eth.getTransactionReceipt.return_value = receipt txinfo = {'gas': gas} web3_mock.eth.getTransaction.return_value = txinfo txid = 'abcdef' assert check_successful_tx(web3=web3_mock, txid=txid) == (receipt, txinfo) web3_mock.eth.getTransactionReceipt.assert_called_with(txid) web3_mock.eth.getTransaction.assert_called_with(txid)
def transfer_tokens(self, token_address: ChecksumAddress, dest: str, amount: int) -> TxReceipt: token_address = to_checksum_address(token_address) dest = to_checksum_address(dest) assert self.is_valid_contract( token_address ), "The token contract does not seem to exist on this address" token_contract = ContractManager(contracts_precompiled_path()).get_contract( CONTRACT_CUSTOM_TOKEN ) token_proxy = self.web3.eth.contract(address=token_address, abi=token_contract["abi"]) assert ( token_proxy.functions.balanceOf(self.owner).call() >= amount ), "Not enough token balances" txhash = token_proxy.functions.transfer(dest, amount).transact({"from": self.owner}) receipt, _ = check_successful_tx(web3=self.web3, txid=txhash, timeout=self.wait) return receipt
def get_weth(self, token_address: str, amount: int) -> Dict[str, Any]: token_address = to_checksum_address(token_address) assert ( self.web3.eth.getBalance(self.owner) > amount ), "Not sufficient ether to make a deposit to WETH contract" assert self.is_valid_contract( token_address ), "The WETH token does not exist on this contract" result = requests.get( f"http://api.etherscan.io/api?module=contract&action=getabi&" f"address=0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" ) weth_abi = result.json()["result"] weth_proxy = self.web3.eth.contract(address=token_address, abi=weth_abi) assert weth_proxy.functions.symbol().call() == "WETH", "This contract is not a WETH token" txhash = weth_proxy.functions.deposit().transact({"from": self.owner, "value": amount}) (receipt, _) = check_successful_tx(web3=self.web3, txid=txhash, timeout=self.wait) return receipt
def deploy( self, contract_name: str, args=None, ): if args is None: args = list() contract_interface = self.contract_manager.get_contract( contract_name, ) # Instantiate and deploy contract contract = self.web3.eth.contract( abi=contract_interface['abi'], bytecode=contract_interface['bin'], ) # Get transaction hash from deployed contract txhash = self.send_deployment_transaction( contract=contract, args=args, ) # Get tx receipt to get contract address LOG.debug( f'Deploying {contract_name} txHash={encode_hex(txhash)}, ' f'contracts version {self.contract_manager.contracts_version}', ) (receipt, tx) = check_successful_tx( web3=self.web3, txid=txhash, timeout=self.wait, ) if not receipt['contractAddress']: # happens with Parity receipt = dict(receipt) receipt['contractAddress'] = tx['creates'] LOG.info( '{0} address: {1}. Gas used: {2}'.format( contract_name, receipt['contractAddress'], receipt['gasUsed'], ), ) return receipt
def deploy(self, contract_name: str, libs: Dict = None, args: Optional[List] = None) -> TxReceipt: if args is None: args = list() contract_interface: CompiledContract = self.contract_manager.get_contract( contract_name) abi = contract_interface["abi"] bytecode = contract_interface["bin"] bytecode_runtime = None if isinstance(libs, dict) and len(libs.keys()) > 0: bytecode = link_code(bytecode, libs) bytecode_runtime = link_code(contract_interface["bin-runtime"], libs) # Instantiate and deploy contract if bytecode_runtime: contract = self.web3.eth.contract( abi=abi, bytecode=bytecode, bytecode_runtime=bytecode_runtime) else: contract = self.web3.eth.contract( abi=abi, bytecode=bytecode, ) # Get transaction hash from deployed contract txhash = self.send_deployment_transaction(contract=contract, args=args) # Get tx receipt to get contract address LOG.debug( f"Deploying {contract_name} txHash={encode_hex(txhash)}, " f"contracts version {self.contract_manager.contracts_version}") receipt, tx = check_successful_tx(web3=self.web3, txid=txhash, timeout=self.wait) if not receipt["contractAddress"]: # happens with Parity receipt["contractAddress"] = tx["creates"] # type: ignore LOG.info("{0} address: {1}. Gas used: {2}".format( contract_name, receipt["contractAddress"], receipt["gasUsed"])) return receipt
def deprecation_test_setup( deployer, token_amount, channel_participant_deposit_limit: int, token_network_deposit_limit: int, ): deployed_contracts = deploy_raiden_contracts( deployer=deployer, max_num_of_token_networks=1, )['contracts'] token_network_registry_abi = deployer.contract_manager.get_contract_abi( CONTRACT_TOKEN_NETWORK_REGISTRY, ) token_network_registry = deployer.web3.eth.contract( abi=token_network_registry_abi, address=deployed_contracts[CONTRACT_TOKEN_NETWORK_REGISTRY]['address'], ) token_decimals = 18 multiplier = 10**token_decimals token_supply = 10**6 * multiplier token_amount = int(token_amount * multiplier) deployed_token = deploy_token_contract( deployer, token_supply, token_decimals, 'TestToken', 'TTT', CONTRACT_CUSTOM_TOKEN, ) token_address = deployed_token[CONTRACT_CUSTOM_TOKEN] token_abi = deployer.contract_manager.get_contract_abi( CONTRACT_CUSTOM_TOKEN) token_contract = deployer.web3.eth.contract( abi=token_abi, address=token_address, ) # Mint some tokens for the owner txhash = token_contract.functions.mint(token_amount).transact( deployer.transaction, ) log.debug(f'Minting tokens txHash={encode_hex(txhash)}') check_successful_tx(deployer.web3, txhash, deployer.wait) assert token_contract.functions.balanceOf( deployer.owner).call() >= token_amount abi = deployer.contract_manager.get_contract_abi( CONTRACT_TOKEN_NETWORK_REGISTRY) token_network_address = register_token_network( web3=deployer.web3, caller=deployer.owner, token_registry_abi=abi, token_registry_address=deployed_contracts[ CONTRACT_TOKEN_NETWORK_REGISTRY]['address'], token_address=token_address, channel_participant_deposit_limit=channel_participant_deposit_limit, token_network_deposit_limit=token_network_deposit_limit, token_registry_version=deployer.contract_manager.version_string(), wait=deployer.wait, ) token_network_abi = deployer.contract_manager.get_contract_abi( CONTRACT_TOKEN_NETWORK) token_network = deployer.web3.eth.contract( abi=token_network_abi, address=token_network_address, ) log.info( f'Registered the token and created a TokenNetwork contract at {token_network_address}.', ) txhash = token_contract.functions.approve(token_network.address, token_amount).transact( deployer.transaction, ) log.debug( f'Approving tokens for the TokenNetwork contract txHash={encode_hex(txhash)}' ) check_successful_tx(deployer.web3, txhash, deployer.wait) assert token_contract.functions.allowance( deployer.owner, token_network.address, ).call() >= token_amount log.info( f'Approved {token_amount} tokens for the TokenNetwork contract ' f'from owner {deployer.owner}.', ) return (token_network_registry, token_network, token_contract)
def deprecation_test_setup( deployer: ContractDeployer, token_amount: int, channel_participant_deposit_limit: int, token_network_deposit_limit: int, ) -> Tuple: deployed_contracts = deployer.deploy_raiden_contracts( max_num_of_token_networks=1, reuse_secret_registry_from_deploy_file=None, settle_timeout_min=DEPLOY_SETTLE_TIMEOUT_MIN, settle_timeout_max=DEPLOY_SETTLE_TIMEOUT_MAX, )["contracts"] token_network_registry_abi = deployer.contract_manager.get_contract_abi( CONTRACT_TOKEN_NETWORK_REGISTRY ) token_network_registry = deployer.web3.eth.contract( abi=token_network_registry_abi, address=deployed_contracts[CONTRACT_TOKEN_NETWORK_REGISTRY]["address"], ) token_decimals = 18 multiplier = 10 ** token_decimals token_supply = 10 ** 6 * multiplier token_amount = int(token_amount * multiplier) deployed_token = deployer.deploy_token_contract( token_supply, token_decimals, "TestToken", "TTT", CONTRACT_CUSTOM_TOKEN ) token_address = deployed_token[CONTRACT_CUSTOM_TOKEN] token_abi = deployer.contract_manager.get_contract_abi(CONTRACT_CUSTOM_TOKEN) token_contract = deployer.web3.eth.contract(abi=token_abi, address=token_address) # Mint some tokens for the owner txhash = call_and_transact(token_contract.functions.mint(token_amount), deployer.transaction) log.debug(f"Minting tokens txHash={encode_hex(txhash)}") check_successful_tx(deployer.web3, txhash, deployer.wait) assert token_contract.functions.balanceOf(deployer.owner).call() >= token_amount abi = deployer.contract_manager.get_contract_abi(CONTRACT_TOKEN_NETWORK_REGISTRY) token_network_address = deployer.register_token_network( token_registry_abi=abi, token_registry_address=deployed_contracts[CONTRACT_TOKEN_NETWORK_REGISTRY]["address"], token_address=token_address, channel_participant_deposit_limit=channel_participant_deposit_limit, token_network_deposit_limit=token_network_deposit_limit, )["token_network_address"] token_network_abi = deployer.contract_manager.get_contract_abi(CONTRACT_TOKEN_NETWORK) token_network = deployer.web3.eth.contract( abi=token_network_abi, address=token_network_address ) log.info( f"Registered the token and created a TokenNetwork contract at {token_network_address}." ) txhash = call_and_transact( token_contract.functions.approve(token_network.address, token_amount), deployer.transaction, ) log.debug(f"Approving tokens for the TokenNetwork contract txHash={encode_hex(txhash)}") check_successful_tx(deployer.web3, txhash, deployer.wait) assert ( token_contract.functions.allowance(deployer.owner, token_network.address).call() >= token_amount ) log.info( f"Approved {token_amount} tokens for the TokenNetwork contract " f"from owner {deployer.owner}." ) return (token_network_registry, token_network, token_contract)
def open_and_deposit( A: HexAddress, B: HexAddress, token_network: Contract, deployer: ContractDeployer, channel_identifier: Optional[int] = None, txn_success_status: bool = True, ) -> int: try: txhash = call_and_transact( token_network.functions.openChannel( participant1=A, participant2=B, settle_timeout=DEPLOY_SETTLE_TIMEOUT_MIN ), deployer.transaction, ) log.debug(f"Opening a channel between {A} and {B} txHash={encode_hex(txhash)}") check_successful_tx(web3=deployer.web3, txid=txhash, timeout=deployer.wait) # Get the channel identifier channel_identifier = token_network.functions.getChannelIdentifier(A, B).call() success_status = True except ValueError as ex: success_status = False log.info(f"Cannot open a new channel {ex}") assert ( txn_success_status == success_status ), f"openChannel txn status is {success_status} instead of {txn_success_status}" assert channel_identifier is not None try: txhash = call_and_transact( token_network.functions.setTotalDeposit( channel_identifier=channel_identifier, participant=A, total_deposit=int(MAX_ETH_CHANNEL_PARTICIPANT / 2), partner=B, ), deployer.transaction, ) log.debug( f"Depositing {MAX_ETH_CHANNEL_PARTICIPANT} tokens for {A} in a channel with " f"identifier={channel_identifier} and partner= {B} txHash={encode_hex(txhash)}" ) check_successful_tx(web3=deployer.web3, txid=txhash, timeout=deployer.wait) success_status = True except ValueError as ex: success_status = False log.info(f"Cannot deposit more tokens in channel={channel_identifier}, {ex}") assert ( txn_success_status == success_status ), f"setTotalDeposit txn status is {success_status} instead of {txn_success_status}" try: txhash = call_and_transact( token_network.functions.setTotalDeposit( channel_identifier=channel_identifier, participant=B, total_deposit=int(MAX_ETH_CHANNEL_PARTICIPANT / 2), partner=A, ), deployer.transaction, ) log.debug( f"Depositing {MAX_ETH_CHANNEL_PARTICIPANT} tokens for {B} in a channel with " f"identifier={channel_identifier} and partner= {A} txHash={encode_hex(txhash)}" ) check_successful_tx(web3=deployer.web3, txid=txhash, timeout=deployer.wait) success_status = True except ValueError as ex: success_status = False log.info(f"Cannot deposit more tokens in channel={channel_identifier}, {ex}") assert ( txn_success_status == success_status ), f"setTotalDeposit txn status is {success_status} instead of {txn_success_status}" return channel_identifier
def open_and_deposit( A, B, token_network, deployer, channel_identifier=None, txn_success_status=True, ): try: txhash = token_network.functions.openChannel( A, B, DEPLOY_SETTLE_TIMEOUT_MIN).transact(deployer.transaction, ) log.debug( f'Opening a channel between {A} and {B} txHash={encode_hex(txhash)}' ) check_successful_tx(deployer.web3, txhash, deployer.wait) # Get the channel identifier channel_identifier = token_network.functions.getChannelIdentifier( A, B).call() success_status = True except ValueError as ex: success_status = False log.info(f'Cannot open a new channel {ex}') assert txn_success_status == success_status, \ f'openChannel txn status is {success_status} instead of {txn_success_status}' assert channel_identifier is not None try: txhash = token_network.functions.setTotalDeposit( channel_identifier, A, int(MAX_ETH_CHANNEL_PARTICIPANT / 2), B, ).transact(deployer.transaction, ) log.debug( f'Depositing {MAX_ETH_CHANNEL_PARTICIPANT} tokens for {A} in a channel with ' f'identifier={channel_identifier} and partner= {B} txHash={encode_hex(txhash)}', ) check_successful_tx(deployer.web3, txhash, deployer.wait) success_status = True except ValueError as ex: success_status = False log.info( f'Cannot deposit more tokens in channel={channel_identifier}, {ex}' ) assert txn_success_status == success_status, \ f'setTotalDeposit txn status is {success_status} instead of {txn_success_status}' try: txhash = token_network.functions.setTotalDeposit( channel_identifier, B, int(MAX_ETH_CHANNEL_PARTICIPANT / 2), A, ).transact(deployer.transaction, ) log.debug( f'Depositing {MAX_ETH_CHANNEL_PARTICIPANT} tokens for {B} in a channel with ' f'identifier={channel_identifier} and partner= {A} txHash={encode_hex(txhash)}', ) check_successful_tx(deployer.web3, txhash, deployer.wait) success_status = True except ValueError as ex: success_status = False log.info( f'Cannot deposit more tokens in channel={channel_identifier}, {ex}' ) assert txn_success_status == success_status, \ f'setTotalDeposit txn status is {success_status} instead of {txn_success_status}' return channel_identifier