def _add_token( self, token_address: TokenAddress, additional_arguments: Dict, ) -> Address: if not is_binary_address(token_address): raise InvalidAddress('Expected binary address format for token') token_proxy = Token( jsonrpc_client=self.client, token_address=token_address, contract_manager=self.contract_manager, ) if token_proxy.total_supply() == '': raise InvalidToken( 'Given token address does not follow the ERC20 standard (missing totalSupply()', ) log_details = { 'node': pex(self.node_address), 'token_address': pex(token_address), 'registry_address': pex(self.address), } log.debug('createERC20TokenNetwork called', **log_details) checking_block = self.client.get_checking_block() error_prefix = 'Call to createERC20TokenNetwork will fail' kwarguments = {'_token_address': token_address} kwarguments.update(additional_arguments) gas_limit = self.proxy.estimate_gas( checking_block, 'createERC20TokenNetwork', **kwarguments, ) if gas_limit: error_prefix = 'Call to createERC20TokenNetwork failed' transaction_hash = self.proxy.transact( 'createERC20TokenNetwork', safe_gas_limit(gas_limit, GAS_REQUIRED_FOR_CREATE_ERC20_TOKEN_NETWORK), **kwarguments, ) self.client.poll(transaction_hash) receipt_or_none = check_transaction_threw(self.client, transaction_hash) transaction_executed = gas_limit is not None if not transaction_executed or receipt_or_none: error_type = RaidenUnrecoverableError if transaction_executed: block = receipt_or_none['blockNumber'] else: block = checking_block required_gas = gas_limit if gas_limit else GAS_REQUIRED_FOR_CREATE_ERC20_TOKEN_NETWORK self.proxy.jsonrpc_client.check_for_insufficient_eth( transaction_name='createERC20TokenNetwork', transaction_executed=transaction_executed, required_gas=required_gas, block_identifier=block, ) msg = '' if self.get_token_network(token_address, block): msg = 'Token already registered' error_type = RaidenRecoverableError error_msg = f'{error_prefix}. {msg}' if error_type == RaidenRecoverableError: log.warning(error_msg, **log_details) else: log.critical(error_msg, **log_details) raise error_type(error_msg) token_network_address = self.get_token_network(token_address, 'latest') if token_network_address is None: msg = 'createERC20TokenNetwork succeeded but token network address is Null' log.critical(msg, **log_details) raise RuntimeError(msg) log.info( 'createERC20TokenNetwork successful', token_network_address=pex(token_network_address), **log_details, ) return token_network_address
def add_token( self, token_address: TokenAddress, channel_participant_deposit_limit: TokenAmount, token_network_deposit_limit: TokenAmount, given_block_identifier: BlockIdentifier, ) -> Tuple[TransactionHash, TokenNetworkAddress]: """ Register token of `token_address` with the token network. The limits apply for version 0.13.0 and above of raiden-contracts, since instantiation also takes the limits as constructor arguments. """ if given_block_identifier == BLOCK_ID_LATEST: raise ValueError( 'Calling a proxy with "latest" is usually wrong because ' "the result of the precondition check is not precisely predictable." ) if token_address == NULL_ADDRESS_BYTES: raise InvalidTokenAddress( "The call to register a token at 0x00..00 will fail.") if token_network_deposit_limit <= 0: raise InvalidTokenNetworkDepositLimit( f"Token network deposit limit must be larger than zero, " f"{token_network_deposit_limit} given.") if channel_participant_deposit_limit <= 0: raise InvalidTokenNetworkDepositLimit( f"Participant deposit limit must be larger than zero, " f"{channel_participant_deposit_limit} given") if channel_participant_deposit_limit > token_network_deposit_limit: raise InvalidChannelParticipantDepositLimit( f"Participant deposit limit must be smaller than the network " f"deposit limit, {channel_participant_deposit_limit} is larger " f"than {token_network_deposit_limit}.") token_proxy = self.proxy_manager.token(token_address, given_block_identifier) try: token_supply = token_proxy.total_supply( block_identifier=given_block_identifier) already_registered = self.get_token_network( token_address=token_address, block_identifier=given_block_identifier) deprecation_executor = self.get_deprecation_executor( block_identifier=given_block_identifier) settlement_timeout_min = self.settlement_timeout_min( block_identifier=given_block_identifier) settlement_timeout_max = self.settlement_timeout_max( block_identifier=given_block_identifier) chain_id = self.get_chain_id( block_identifier=given_block_identifier) secret_registry_address = self.get_secret_registry_address( block_identifier=given_block_identifier) max_token_networks = self.get_max_token_networks( block_identifier=given_block_identifier) token_networks_created = self.get_token_network_created( block_identifier=given_block_identifier) except ValueError: # If `given_block_identifier` has been pruned the checks cannot be performed pass except BadFunctionCallOutput: raise_on_call_returned_empty(given_block_identifier) else: if token_networks_created >= max_token_networks: raise MaxTokenNetworkNumberReached( f"Number of token networks will exceed the maximum of {max_token_networks}" ) if token_supply is None: raise InvalidToken("Given token address does not follow the " "ERC20 standard (missing `totalSupply()`)") if already_registered: raise BrokenPreconditionError( "The token is already registered in the TokenNetworkRegistry." ) if deprecation_executor == NULL_ADDRESS_BYTES: raise BrokenPreconditionError( "The deprecation executor property for the TokenNetworkRegistry is invalid." ) if chain_id == 0: raise BrokenPreconditionError( "The chain ID property for the TokenNetworkRegistry is invalid." ) if chain_id != self.rpc_client.chain_id: raise BrokenPreconditionError( f"The provided chain ID {chain_id} does not match the " f"network Raiden is running on: {self.rpc_client.chain_id}." ) if secret_registry_address == NULL_ADDRESS_BYTES: raise BrokenPreconditionError( "The secret registry address for the token network is invalid." ) if settlement_timeout_min == 0: raise BrokenPreconditionError( "The minimum settlement timeout for the token network " "should be larger than zero.") if settlement_timeout_max <= settlement_timeout_min: raise BrokenPreconditionError( "The maximum settlement timeout for the token network " "should be larger than the minimum settlement timeout.") log_details = { "given_block_identifier": format_block_id(given_block_identifier) } return self._add_token( token_address=token_address, channel_participant_deposit_limit=channel_participant_deposit_limit, token_network_deposit_limit=token_network_deposit_limit, log_details=log_details, )
def _add_token(self, token_address: TokenAddress, additional_arguments: Dict) -> Address: if not is_binary_address(token_address): raise InvalidAddress("Expected binary address format for token") token_proxy = Token( jsonrpc_client=self.client, token_address=token_address, contract_manager=self.contract_manager, ) if token_proxy.total_supply() == "": raise InvalidToken( "Given token address does not follow the ERC20 standard (missing totalSupply()" ) log_details = { "node": pex(self.node_address), "token_address": pex(token_address), "registry_address": pex(self.address), } log.debug("createERC20TokenNetwork called", **log_details) checking_block = self.client.get_checking_block() error_prefix = "Call to createERC20TokenNetwork will fail" kwarguments = {"_token_address": token_address} kwarguments.update(additional_arguments) gas_limit = self.proxy.estimate_gas(checking_block, "createERC20TokenNetwork", **kwarguments) if gas_limit: error_prefix = "Call to createERC20TokenNetwork failed" transaction_hash = self.proxy.transact( "createERC20TokenNetwork", safe_gas_limit(gas_limit, GAS_REQUIRED_FOR_CREATE_ERC20_TOKEN_NETWORK), **kwarguments, ) self.client.poll(transaction_hash) receipt_or_none = check_transaction_threw(self.client, transaction_hash) transaction_executed = gas_limit is not None if not transaction_executed or receipt_or_none: if transaction_executed: block = receipt_or_none["blockNumber"] else: block = checking_block required_gas = gas_limit if gas_limit else GAS_REQUIRED_FOR_CREATE_ERC20_TOKEN_NETWORK self.proxy.jsonrpc_client.check_for_insufficient_eth( transaction_name="createERC20TokenNetwork", transaction_executed=transaction_executed, required_gas=required_gas, block_identifier=block, ) if self.get_token_network(token_address, block): error_msg = f"{error_prefix}. Token already registered" log.warning(error_msg, **log_details) raise RaidenRecoverableError(error_msg) error_msg = f"{error_prefix}" log.critical(error_msg, **log_details) raise RaidenUnrecoverableError(error_msg) token_network_address = self.get_token_network(token_address, "latest") if token_network_address is None: msg = "createERC20TokenNetwork succeeded but token network address is Null" log.critical(msg, **log_details) raise RuntimeError(msg) log.info( "createERC20TokenNetwork successful", token_network_address=pex(token_network_address), **log_details, ) return token_network_address
def add_token( self, token_address: TokenAddress, channel_participant_deposit_limit: TokenAmount, token_network_deposit_limit: TokenAmount, block_identifier: BlockSpecification, ) -> TokenNetworkAddress: """ Register token of `token_address` with the token network. The limits apply for version 0.13.0 and above of raiden-contracts, since instantiation also takes the limits as constructor arguments. """ if block_identifier == "latest": raise ValueError( 'Calling a proxy with "latest" is usually wrong because ' "the result of the precondition check is not precisely predictable." ) if token_address == NULL_ADDRESS_BYTES: raise InvalidTokenAddress( "The call to register a token at 0x00..00 will fail.") if token_network_deposit_limit <= 0: raise InvalidTokenNetworkDepositLimit( f"Token network deposit limit of {token_network_deposit_limit} is invalid" ) if channel_participant_deposit_limit > token_network_deposit_limit: raise InvalidChannelParticipantDepositLimit( f"Channel participant deposit limit of " f"{channel_participant_deposit_limit} is invalid") token_proxy = self.proxy_manager.token(token_address) try: token_supply = token_proxy.total_supply( block_identifier=block_identifier) already_registered = self.get_token_network( token_address=token_address, block_identifier=block_identifier) deprecation_executor = self.get_deprecation_executor( block_identifier=block_identifier) settlement_timeout_min = self.settlement_timeout_min( block_identifier=block_identifier) settlement_timeout_max = self.settlement_timeout_max( block_identifier=block_identifier) chain_id = self.get_chain_id(block_identifier=block_identifier) secret_registry_address = self.get_secret_registry_address( block_identifier=block_identifier) max_token_networks = self.get_max_token_networks( block_identifier=block_identifier) token_networks_created = self.get_token_network_created( block_identifier=block_identifier) except ValueError: # If `block_identifier` has been pruned the checks cannot be performed pass except BadFunctionCallOutput: raise_on_call_returned_empty(block_identifier) else: if token_networks_created >= max_token_networks: raise BrokenPreconditionError( f"Number of token networks will exceed the max of {max_token_networks}" ) if token_supply == "": raise InvalidToken("Given token address does not follow the " "ERC20 standard (missing `totalSupply()`)") if already_registered: raise BrokenPreconditionError( "The token is already registered in the TokenNetworkRegistry." ) if deprecation_executor == NULL_ADDRESS_BYTES: raise BrokenPreconditionError( "The deprecation executor property for the TokenNetworkRegistry is invalid." ) if chain_id == 0: raise BrokenPreconditionError( "The chain ID property for the TokenNetworkRegistry is invalid." ) if secret_registry_address == NULL_ADDRESS_BYTES: raise BrokenPreconditionError( "The secret registry address for the token network is invalid." ) if settlement_timeout_min == 0: raise BrokenPreconditionError( "The minimum settlement timeout for the token network " "should be larger than zero.") if settlement_timeout_min == 0: raise BrokenPreconditionError( "The minimum settlement timeout for the token network " "should be larger than zero.") if settlement_timeout_max <= settlement_timeout_min: raise BrokenPreconditionError( "The maximum settlement timeout for the token network " "should be larger than the minimum settlement timeout.") log_details = { "node": to_checksum_address(self.node_address), "contract": to_checksum_address(self.address), "token_address": to_checksum_address(token_address), } with log_transaction(log, "add_token", log_details): return self._add_token( token_address=token_address, channel_participant_deposit_limit= channel_participant_deposit_limit, token_network_deposit_limit=token_network_deposit_limit, log_details=log_details, )