def validate_gas_reserve(channels_to_open: int, raiden) -> int: has_enough_reserve, estimated_required_reserve = has_enough_gas_reserve( raiden, channels_to_open) if not has_enough_reserve: raise InsufficientGasReserve(( "The account balance is below the estimated amount necessary to " "finish the lifecycles of all active channels. A balance of at " f"least {estimated_required_reserve} wei is required.")) return estimated_required_reserve
def token_network_connect( self, registry_address: TokenNetworkRegistryAddress, token_address: TokenAddress, funds: TokenAmount, initial_channel_target: int = 3, joinable_funds_target: float = 0.4, ) -> None: """ Automatically maintain channels open for the given token network. Args: token_address: the ERC20 token network to connect to. funds: the amount of funds that can be used by the ConnectionManager. initial_channel_target: number of channels to open proactively. joinable_funds_target: fraction of the funds that will be used to join channels opened by other participants. """ if not is_binary_address(registry_address): raise InvalidBinaryAddress( "registry_address must be a valid address in binary") if not is_binary_address(token_address): raise InvalidBinaryAddress( "token_address must be a valid address in binary") token_network_address = views.get_token_network_address_by_token_address( chain_state=views.state_from_raiden(self.raiden), token_network_registry_address=registry_address, token_address=token_address, ) if token_network_address is None: raise UnknownTokenAddress( f"Token {to_checksum_address(token_address)} is not registered " f"with the network {to_checksum_address(registry_address)}.") connection_manager = self.raiden.connection_manager_for_token_network( token_network_address) has_enough_reserve, estimated_required_reserve = has_enough_gas_reserve( raiden=self.raiden, channels_to_open=initial_channel_target) if not has_enough_reserve: raise InsufficientGasReserve( "The account balance is below the estimated amount necessary to " "finish the lifecycles of all active channels. A balance of at " f"least {estimated_required_reserve} wei is required.") connection_manager.connect( funds=funds, initial_channel_target=initial_channel_target, joinable_funds_target=joinable_funds_target, )
def token_network_connect( self, registry_address: typing.PaymentNetworkID, token_address: typing.TokenAddress, funds: typing.TokenAmount, initial_channel_target: int = 3, joinable_funds_target: float = 0.4, ) -> None: """ Automatically maintain channels open for the given token network. Args: token_address: the ERC20 token network to connect to. funds: the amount of funds that can be used by the ConnectionMananger. initial_channel_target: number of channels to open proactively. joinable_funds_target: fraction of the funds that will be used to join channels opened by other participants. """ if not is_binary_address(registry_address): raise InvalidAddress( 'registry_address must be a valid address in binary') if not is_binary_address(token_address): raise InvalidAddress( 'token_address must be a valid address in binary') token_network_identifier = views.get_token_network_identifier_by_token_address( views.state_from_raiden(self.raiden), payment_network_id=registry_address, token_address=token_address, ) connection_manager = self.raiden.connection_manager_for_token_network( token_network_identifier, ) has_enough_reserve, estimated_required_reserve = has_enough_gas_reserve( self.raiden, channels_to_open=initial_channel_target, ) if not has_enough_reserve: raise InsufficientGasReserve(( 'The account balance is below the estimated amount necessary to ' 'finish the lifecycles of all active channels. A balance of at ' f'least {estimated_required_reserve} wei is required.')) connection_manager.connect( funds, initial_channel_target=initial_channel_target, joinable_funds_target=joinable_funds_target, )
def token_network_connect( self, registry_address: typing.PaymentNetworkID, token_address: typing.TokenAddress, funds: typing.TokenAmount, initial_channel_target: int = 3, joinable_funds_target: float = 0.4, ) -> None: """ Automatically maintain channels open for the given token network. Args: token_address: the ERC20 token network to connect to. funds: the amount of funds that can be used by the ConnectionMananger. initial_channel_target: number of channels to open proactively. joinable_funds_target: fraction of the funds that will be used to join channels opened by other participants. """ if not is_binary_address(registry_address): raise InvalidAddress('registry_address must be a valid address in binary') if not is_binary_address(token_address): raise InvalidAddress('token_address must be a valid address in binary') token_network_identifier = views.get_token_network_identifier_by_token_address( chain_state=views.state_from_raiden(self.raiden), payment_network_id=registry_address, token_address=token_address, ) connection_manager = self.raiden.connection_manager_for_token_network( token_network_identifier, ) has_enough_reserve, estimated_required_reserve = has_enough_gas_reserve( raiden=self.raiden, channels_to_open=initial_channel_target, ) if not has_enough_reserve: raise InsufficientGasReserve(( 'The account balance is below the estimated amount necessary to ' 'finish the lifecycles of all active channels. A balance of at ' f'least {estimated_required_reserve} wei is required.' )) connection_manager.connect( funds=funds, initial_channel_target=initial_channel_target, joinable_funds_target=joinable_funds_target, )
def check_gas_reserve(raiden): """ Check periodically for gas reserve in the account """ while True: has_enough_balance, estimated_required_balance = gas_reserve.has_enough_gas_reserve( raiden, channels_to_open=1) estimated_required_balance_eth = Web3.fromWei( estimated_required_balance, "ether") if not has_enough_balance: log.info("Missing gas reserve", required_wei=estimated_required_balance) click.secho( ("WARNING\n" "Your account's balance is below the estimated gas reserve of " f"{estimated_required_balance_eth} eth. This may lead to a loss of " "of funds because your account will be unable to perform on-chain " "transactions. Please add funds to your account as soon as possible." ), fg="red", ) gevent.sleep(CHECK_GAS_RESERVE_INTERVAL)
def check_gas_reserve(raiden): """ Check periodically for gas reserve in the account """ while True: has_enough_balance, estimated_required_balance = gas_reserve.has_enough_gas_reserve( raiden, channels_to_open=0, ) estimated_required_balance_eth = Web3.fromWei(estimated_required_balance, 'ether') if not has_enough_balance: log.info('Missing gas reserve', required_wei=estimated_required_balance) click.secho( ( 'WARNING\n' "Your account's balance is below the estimated gas reserve of " f'{estimated_required_balance_eth} eth. This may lead to a loss of ' 'of funds because your account will be unable to perform on-chain ' 'transactions. Please add funds to your account as soon as possible.' ), fg='red', ) gevent.sleep(CHECK_GAS_RESERVE_INTERVAL)
def channel_open( self, registry_address: typing.PaymentNetworkID, token_address: typing.TokenAddress, partner_address: typing.Address, settle_timeout: typing.BlockTimeout = None, retry_timeout: typing.NetworkTimeout = DEFAULT_RETRY_TIMEOUT, ) -> typing.ChannelID: """ Open a channel with the peer at `partner_address` with the given `token_address`. """ if settle_timeout is None: settle_timeout = self.raiden.config['settle_timeout'] if settle_timeout < self.raiden.config['reveal_timeout'] * 2: raise InvalidSettleTimeout( 'settle_timeout can not be smaller than double the reveal_timeout', ) if not is_binary_address(registry_address): raise InvalidAddress( 'Expected binary address format for registry in channel open') if not is_binary_address(token_address): raise InvalidAddress( 'Expected binary address format for token in channel open') if not is_binary_address(partner_address): raise InvalidAddress( 'Expected binary address format for partner in channel open') chain_state = views.state_from_raiden(self.raiden) channel_state = views.get_channelstate_for( chain_state, registry_address, token_address, partner_address, ) if channel_state: raise DuplicatedChannelError( 'Channel with given partner address already exists') registry = self.raiden.chain.token_network_registry(registry_address) token_network_address = registry.get_token_network(token_address) if token_network_address is None: raise TokenNotRegistered( 'Token network for token %s does not exist' % to_checksum_address(token_address), ) token_network = self.raiden.chain.token_network( registry.get_token_network(token_address), ) has_enough_reserve, estimated_required_reserve = has_enough_gas_reserve( self.raiden, channels_to_open=1, ) if not has_enough_reserve: raise InsufficientGasReserve(( 'The account balance is below the estimated amount necessary to ' 'finish the lifecycles of all active channels. A balance of at ' f'least {estimated_required_reserve} wei is required.')) try: token_network.new_netting_channel( partner_address, settle_timeout, ) except DuplicatedChannelError: log.info('partner opened channel first') waiting.wait_for_newchannel( self.raiden, registry_address, token_address, partner_address, retry_timeout, ) chain_state = views.state_from_raiden(self.raiden) channel_state = views.get_channelstate_for( chain_state, registry_address, token_address, partner_address, ) return channel_state.identifier
def channel_open( self, registry_address: typing.PaymentNetworkID, token_address: typing.TokenAddress, partner_address: typing.Address, settle_timeout: typing.BlockTimeout = None, retry_timeout: typing.NetworkTimeout = DEFAULT_RETRY_TIMEOUT, ) -> typing.ChannelID: """ Open a channel with the peer at `partner_address` with the given `token_address`. """ if settle_timeout is None: settle_timeout = self.raiden.config['settle_timeout'] if settle_timeout < self.raiden.config['reveal_timeout'] * 2: raise InvalidSettleTimeout( 'settle_timeout can not be smaller than double the reveal_timeout', ) if not is_binary_address(registry_address): raise InvalidAddress('Expected binary address format for registry in channel open') if not is_binary_address(token_address): raise InvalidAddress('Expected binary address format for token in channel open') if not is_binary_address(partner_address): raise InvalidAddress('Expected binary address format for partner in channel open') chain_state = views.state_from_raiden(self.raiden) channel_state = views.get_channelstate_for( chain_state=chain_state, payment_network_id=registry_address, token_address=token_address, partner_address=partner_address, ) if channel_state: raise DuplicatedChannelError('Channel with given partner address already exists') registry = self.raiden.chain.token_network_registry(registry_address) token_network_address = registry.get_token_network(token_address) if token_network_address is None: raise TokenNotRegistered( 'Token network for token %s does not exist' % to_checksum_address(token_address), ) token_network = self.raiden.chain.token_network( registry.get_token_network(token_address), ) with self.raiden.gas_reserve_lock: has_enough_reserve, estimated_required_reserve = has_enough_gas_reserve( self.raiden, channels_to_open=1, ) if not has_enough_reserve: raise InsufficientGasReserve(( 'The account balance is below the estimated amount necessary to ' 'finish the lifecycles of all active channels. A balance of at ' f'least {estimated_required_reserve} wei is required.' )) try: token_network.new_netting_channel( partner=partner_address, settle_timeout=settle_timeout, ) except DuplicatedChannelError: log.info('partner opened channel first') waiting.wait_for_newchannel( raiden=self.raiden, payment_network_id=registry_address, token_address=token_address, partner_address=partner_address, retry_timeout=retry_timeout, ) chain_state = views.state_from_raiden(self.raiden) channel_state = views.get_channelstate_for( chain_state=chain_state, payment_network_id=registry_address, token_address=token_address, partner_address=partner_address, ) return channel_state.identifier
def channel_open( self, registry_address: PaymentNetworkID, token_address: TokenAddress, partner_address: Address, settle_timeout: BlockTimeout = None, retry_timeout: NetworkTimeout = DEFAULT_RETRY_TIMEOUT, ) -> ChannelID: """ Open a channel with the peer at `partner_address` with the given `token_address`. """ if settle_timeout is None: settle_timeout = self.raiden.config["settle_timeout"] if settle_timeout < self.raiden.config["reveal_timeout"] * 2: raise InvalidSettleTimeout( "settle_timeout can not be smaller than double the reveal_timeout" ) if not is_binary_address(registry_address): raise InvalidAddress("Expected binary address format for registry in channel open") if not is_binary_address(token_address): raise InvalidAddress("Expected binary address format for token in channel open") if not is_binary_address(partner_address): raise InvalidAddress("Expected binary address format for partner in channel open") chain_state = views.state_from_raiden(self.raiden) channel_state = views.get_channelstate_for( chain_state=chain_state, payment_network_id=registry_address, token_address=token_address, partner_address=partner_address, ) if channel_state: raise DuplicatedChannelError("Channel with given partner address already exists") registry = self.raiden.chain.token_network_registry(registry_address) token_network_address = registry.get_token_network(token_address) if token_network_address is None: raise TokenNotRegistered( "Token network for token %s does not exist" % to_checksum_address(token_address) ) token_network = self.raiden.chain.token_network(registry.get_token_network(token_address)) with self.raiden.gas_reserve_lock: has_enough_reserve, estimated_required_reserve = has_enough_gas_reserve( self.raiden, channels_to_open=1 ) if not has_enough_reserve: raise InsufficientGasReserve( ( "The account balance is below the estimated amount necessary to " "finish the lifecycles of all active channels. A balance of at " f"least {estimated_required_reserve} wei is required." ) ) try: token_network.new_netting_channel( partner=partner_address, settle_timeout=settle_timeout, given_block_identifier=views.state_from_raiden(self.raiden).block_hash, ) except DuplicatedChannelError: log.info("partner opened channel first") waiting.wait_for_newchannel( raiden=self.raiden, payment_network_id=registry_address, token_address=token_address, partner_address=partner_address, retry_timeout=retry_timeout, ) chain_state = views.state_from_raiden(self.raiden) channel_state = views.get_channelstate_for( chain_state=chain_state, payment_network_id=registry_address, token_address=token_address, partner_address=partner_address, ) assert channel_state, f"channel {channel_state} is gone" return channel_state.identifier
def channel_open( self, registry_address: TokenNetworkRegistryAddress, token_address: TokenAddress, partner_address: Address, settle_timeout: BlockTimeout = None, reveal_timeout: BlockTimeout = None, retry_timeout: NetworkTimeout = DEFAULT_RETRY_TIMEOUT, ) -> ChannelID: """ Open a channel with the peer at `partner_address` with the given `token_address`. """ if settle_timeout is None: settle_timeout = self.raiden.config.settle_timeout if reveal_timeout is None: reveal_timeout = self.raiden.config.reveal_timeout if reveal_timeout <= 0: raise InvalidRevealTimeout( "reveal_timeout should be larger than zero") if settle_timeout < reveal_timeout * 2: raise InvalidSettleTimeout( "`settle_timeout` can not be smaller than double the " "`reveal_timeout`.\n " "\n " "The setting `reveal_timeout` determines the maximum number of " "blocks it should take a transaction to be mined when the " "blockchain is under congestion. This setting determines the " "when a node must go on-chain to register a secret, and it is " "therefore the lower bound of the lock expiration. The " "`settle_timeout` determines when a channel can be settled " "on-chain, for this operation to be safe all locks must have " "been resolved, for this reason the `settle_timeout` has to be " "larger than `reveal_timeout`.") if not is_binary_address(registry_address): raise InvalidBinaryAddress( "Expected binary address format for registry in channel open") if not is_binary_address(token_address): raise InvalidBinaryAddress( "Expected binary address format for token in channel open") if not is_binary_address(partner_address): raise InvalidBinaryAddress( "Expected binary address format for partner in channel open") confirmed_block_identifier = views.get_confirmed_blockhash(self.raiden) registry = self.raiden.proxy_manager.token_network_registry( registry_address, block_identifier=confirmed_block_identifier) settlement_timeout_min = registry.settlement_timeout_min( block_identifier=confirmed_block_identifier) settlement_timeout_max = registry.settlement_timeout_max( block_identifier=confirmed_block_identifier) if settle_timeout < settlement_timeout_min: raise InvalidSettleTimeout( f"Settlement timeout should be at least {settlement_timeout_min}" ) if settle_timeout > settlement_timeout_max: raise InvalidSettleTimeout( f"Settlement timeout exceeds max of {settlement_timeout_max}") token_network_address = registry.get_token_network( token_address=token_address, block_identifier=confirmed_block_identifier) if token_network_address is None: raise TokenNotRegistered( "Token network for token %s does not exist" % to_checksum_address(token_address)) token_network = self.raiden.proxy_manager.token_network( address=token_network_address, block_identifier=confirmed_block_identifier) safety_deprecation_switch = token_network.safety_deprecation_switch( block_identifier=confirmed_block_identifier) if safety_deprecation_switch: msg = ( "This token_network has been deprecated. New channels cannot be " "open for this network, usage of the newly deployed token " "network contract is highly encouraged.") raise TokenNetworkDeprecated(msg) duplicated_channel = self.is_already_existing_channel( token_network_address=token_network_address, partner_address=partner_address, block_identifier=confirmed_block_identifier, ) if duplicated_channel: raise DuplicatedChannelError( f"A channel with {to_checksum_address(partner_address)} for token " f"{to_checksum_address(token_address)} already exists. " f"(At blockhash: {confirmed_block_identifier.hex()})") has_enough_reserve, estimated_required_reserve = has_enough_gas_reserve( self.raiden, channels_to_open=1) if not has_enough_reserve: raise InsufficientGasReserve( "The account balance is below the estimated amount necessary to " "finish the lifecycles of all active channels. A balance of at " f"least {estimated_required_reserve} wei is required.") try: token_network.new_netting_channel( partner=partner_address, settle_timeout=settle_timeout, given_block_identifier=confirmed_block_identifier, ) except DuplicatedChannelError: log.info("partner opened channel first") except RaidenRecoverableError: # The channel may have been created in the pending block. duplicated_channel = self.is_already_existing_channel( token_network_address=token_network_address, partner_address=partner_address) if duplicated_channel: log.info("Channel has already been opened") else: raise waiting.wait_for_newchannel( raiden=self.raiden, token_network_registry_address=registry_address, token_address=token_address, partner_address=partner_address, retry_timeout=retry_timeout, ) chain_state = views.state_from_raiden(self.raiden) channel_state = views.get_channelstate_for( chain_state=chain_state, token_network_registry_address=registry_address, token_address=token_address, partner_address=partner_address, ) assert channel_state, f"channel {channel_state} is gone" self.raiden.set_channel_reveal_timeout( canonical_identifier=channel_state.canonical_identifier, reveal_timeout=reveal_timeout) return channel_state.identifier