def get_random_pfs( service_registry: ServiceRegistry, block_identifier: BlockIdentifier, pathfinding_max_fee: TokenAmount, ) -> Optional[str]: """Selects a random PFS from service_registry. Returns a tuple of the chosen services url and eth address. If there are no PFS in the given registry, it returns (None, None). """ number_of_addresses = service_registry.ever_made_deposits_len( block_identifier=block_identifier) indices_to_try = list(range(number_of_addresses)) random.shuffle(indices_to_try) while indices_to_try: index = indices_to_try.pop() url = get_valid_pfs_url( service_registry=service_registry, index_in_service_registry=index, block_identifier=block_identifier, pathfinding_max_fee=pathfinding_max_fee, ) if url: return url return None
def service_registry(self, address: Address) -> ServiceRegistry: with self._service_registry_creation_lock: if address not in self.address_to_service_registry: self.address_to_service_registry[address] = ServiceRegistry( jsonrpc_client=self.client, service_registry_address=address, contract_manager=self.contract_manager, ) return self.address_to_service_registry[address]
def get_random_service(service_registry: ServiceRegistry, block_identifier: BlockSpecification) -> Optional[str]: """Selects a random PFS from service_registry. Returns a tuple of the chosen services url and eth address. If there are no PFS in the given registry, it returns (None, None). """ count = service_registry.service_count(block_identifier=block_identifier) if count == 0: return None index = random.SystemRandom().randint(0, count - 1) address = service_registry.get_service_address( block_identifier=block_identifier, index=index) # We are using the same blockhash for both blockchain queries so the address # should exist for this query. Additionally at the moment there is no way for # services to be removed from the registry. assert address, "address should exist for this index" url = service_registry.get_service_url(block_identifier=block_identifier, service_hex_address=address) return url
def get_valid_pfs_url( service_registry: ServiceRegistry, index_in_service_registry: int, block_identifier: BlockIdentifier, pathfinding_max_fee: TokenAmount, ) -> Optional[str]: """Returns the URL for the PFS identified by the given index Checks validity of registration in the ServiceRegistry contract and checks the price from the PFS' info endpoint. Returns PFS URL or None (if any check fails). """ address = service_registry.ever_made_deposits( block_identifier=block_identifier, index=index_in_service_registry ) if not address: return None if not service_registry.has_valid_registration( service_address=address, block_identifier=block_identifier ): return None url = service_registry.get_service_url( block_identifier=block_identifier, service_address=address ) if not url: return None try: pfs_info = get_pfs_info(url) except ServiceRequestFailed: return None if pfs_info.price > pathfinding_max_fee: return None return url
def deploy_service_registry_and_set_urls( private_keys, web3, contract_manager, service_registry_address) -> Tuple[ServiceRegistry, List[str]]: urls = ["http://foo", "http://boo", "http://coo"] block_identifier = BLOCK_ID_LATEST c1_client = JSONRPCClient(web3, private_keys[0]) c1_service_proxy = ServiceRegistry( jsonrpc_client=c1_client, service_registry_address=service_registry_address, contract_manager=contract_manager, block_identifier=block_identifier, ) token_address = c1_service_proxy.token_address( block_identifier=block_identifier) c1_token_proxy = CustomToken( jsonrpc_client=c1_client, token_address=token_address, contract_manager=contract_manager, block_identifier=block_identifier, ) c2_client = JSONRPCClient(web3, private_keys[1]) c2_service_proxy = ServiceRegistry( jsonrpc_client=c2_client, service_registry_address=service_registry_address, contract_manager=contract_manager, block_identifier=block_identifier, ) c2_token_proxy = CustomToken( jsonrpc_client=c2_client, token_address=token_address, contract_manager=contract_manager, block_identifier=block_identifier, ) c3_client = JSONRPCClient(web3, private_keys[2]) c3_service_proxy = ServiceRegistry( jsonrpc_client=c3_client, service_registry_address=service_registry_address, contract_manager=contract_manager, block_identifier=block_identifier, ) c3_token_proxy = CustomToken( jsonrpc_client=c3_client, token_address=token_address, contract_manager=contract_manager, block_identifier=block_identifier, ) # Test that getting a random service for an empty registry returns None pfs_address = get_random_pfs(c1_service_proxy, BLOCK_ID_LATEST, pathfinding_max_fee=TokenAmount(1)) assert pfs_address is None log_details: Dict[str, Any] = {} # Test that setting the urls works c1_price = c1_service_proxy.current_price(block_identifier=BLOCK_ID_LATEST) c1_token_proxy.mint_for(c1_price, c1_client.address) assert c1_token_proxy.balance_of(c1_client.address) > 0 c1_token_proxy.approve(allowed_address=service_registry_address, allowance=c1_price) c1_service_proxy.deposit(block_identifier=BLOCK_ID_LATEST, limit_amount=c1_price) c1_service_proxy.set_url(urls[0]) c2_price = c2_service_proxy.current_price(block_identifier=BLOCK_ID_LATEST) c2_token_proxy.mint_for(c2_price, c2_client.address) assert c2_token_proxy.balance_of(c2_client.address) > 0 c2_token_proxy.approve(allowed_address=service_registry_address, allowance=c2_price) transaction_hash = c2_service_proxy.deposit( block_identifier=BLOCK_ID_LATEST, limit_amount=c2_price) assert is_tx_hash_bytes(transaction_hash) transaction_hash = c2_service_proxy.set_url(urls[1]) assert is_tx_hash_bytes(transaction_hash) c3_price = c3_service_proxy.current_price(block_identifier=BLOCK_ID_LATEST) c3_token_proxy.mint_for(c3_price, c3_client.address) assert c3_token_proxy.balance_of(c3_client.address) > 0 c3_token_proxy.approve(allowed_address=service_registry_address, allowance=c3_price) c3_service_proxy.deposit(block_identifier=BLOCK_ID_LATEST, limit_amount=c3_price) c3_token_proxy.client.estimate_gas(c3_token_proxy.proxy, "mint", log_details, c3_price) c3_token_proxy.approve(allowed_address=service_registry_address, allowance=c3_price) c3_service_proxy.set_url(urls[2]) return c1_service_proxy, urls
def deploy_service_registry_and_set_urls( private_keys, web3, contract_manager, service_registry_address, ) -> Tuple[ServiceRegistry, List[str]]: urls = ['http://foo', 'http://boo', 'http://coo'] c1_client = JSONRPCClient(web3, private_keys[0]) c1_service_proxy = ServiceRegistry( jsonrpc_client=c1_client, service_registry_address=service_registry_address, contract_manager=contract_manager, ) c2_client = JSONRPCClient(web3, private_keys[1]) c2_service_proxy = ServiceRegistry( jsonrpc_client=c2_client, service_registry_address=service_registry_address, contract_manager=contract_manager, ) c3_client = JSONRPCClient(web3, private_keys[2]) c3_service_proxy = ServiceRegistry( jsonrpc_client=c3_client, service_registry_address=service_registry_address, contract_manager=contract_manager, ) # Test that getting a random service for an empty registry returns None pfs_address, pfs_eth_address = get_random_service(c1_service_proxy, 'latest') assert pfs_address is None assert pfs_eth_address is None # Test that setting the urls works c1_service_proxy.set_url(urls[0]) c2_service_proxy.set_url(urls[1]) c3_service_proxy.set_url(urls[2]) return c1_service_proxy, urls
def deploy_service_registry_and_set_urls( private_keys, web3, contract_manager, service_registry_address) -> Tuple[ServiceRegistry, List[str]]: urls = ["http://foo", "http://boo", "http://coo"] c1_client = JSONRPCClient(web3, private_keys[0]) c1_service_proxy = ServiceRegistry( jsonrpc_client=c1_client, service_registry_address=service_registry_address, contract_manager=contract_manager, ) token_address = c1_service_proxy.token_address(block_identifier="latest") c1_token_proxy = Token(jsonrpc_client=c1_client, token_address=token_address, contract_manager=contract_manager) c2_client = JSONRPCClient(web3, private_keys[1]) c2_service_proxy = ServiceRegistry( jsonrpc_client=c2_client, service_registry_address=service_registry_address, contract_manager=contract_manager, ) c2_token_proxy = Token(jsonrpc_client=c2_client, token_address=token_address, contract_manager=contract_manager) c3_client = JSONRPCClient(web3, private_keys[2]) c3_service_proxy = ServiceRegistry( jsonrpc_client=c3_client, service_registry_address=service_registry_address, contract_manager=contract_manager, ) c3_token_proxy = Token(jsonrpc_client=c3_client, token_address=token_address, contract_manager=contract_manager) # Test that getting a random service for an empty registry returns None pfs_address = get_random_pfs(c1_service_proxy, "latest", pathfinding_max_fee=TokenAmount(1)) assert pfs_address is None # Test that setting the urls works c1_price = c1_service_proxy.current_price(block_identifier="latest") tx = c1_token_proxy.proxy.transact("mint", 1000000, c1_price) receipt = c1_client.poll(tx) assert not check_transaction_threw(receipt=receipt) assert c1_token_proxy.balance_of(c1_client.address) > 0 c1_token_proxy.approve(allowed_address=service_registry_address, allowance=c1_price) c1_service_proxy.deposit(block_identifier="latest", limit_amount=c1_price) c1_service_proxy.set_url(urls[0]) c2_price = c2_service_proxy.current_price(block_identifier="latest") tx = c2_token_proxy.proxy.transact("mint", 1000000, c2_price) receipt = c2_client.poll(tx) assert not check_transaction_threw(receipt=receipt) assert c2_token_proxy.balance_of(c2_client.address) > 0 c2_token_proxy.approve(allowed_address=service_registry_address, allowance=c2_price) c2_service_proxy.deposit(block_identifier="latest", limit_amount=c2_price) c2_service_proxy.set_url(urls[1]) c3_price = c3_service_proxy.current_price(block_identifier="latest") tx = c3_token_proxy.proxy.transact("mint", 1000000, c3_price) receipt = c3_client.poll(tx) assert not check_transaction_threw(receipt=receipt) assert c3_token_proxy.balance_of(c3_client.address) > 0 c3_token_proxy.approve(allowed_address=service_registry_address, allowance=c3_price) c3_service_proxy.deposit(block_identifier="latest", limit_amount=c3_price) c3_token_proxy.proxy.transact("mint", 1000000, c3_price) c3_token_proxy.approve(allowed_address=service_registry_address, allowance=c3_price) c3_service_proxy.set_url(urls[2]) return c1_service_proxy, urls