diff --git a/electrumx/lib/coins.py b/electrumx/lib/coins.py index 905b423..2cce41d 100644 --- a/electrumx/lib/coins.py +++ b/electrumx/lib/coins.py @@ -111,10 +111,6 @@ class Coin(object): url = 'http://' + url return url + '/' - @classmethod - def daemon_urls(cls, urls): - return [cls.sanitize_url(url) for url in urls.split(',')] - @classmethod def genesis_block(cls, block): '''Check the Genesis block is the right one for this coin. diff --git a/electrumx/server/daemon.py b/electrumx/server/daemon.py index a33a44c..0136dda 100644 --- a/electrumx/server/daemon.py +++ b/electrumx/server/daemon.py @@ -38,31 +38,36 @@ class Daemon(object): class DaemonWarmingUpError(Exception): '''Raised when the daemon returns an error in its results.''' - def __init__(self, coin, urls, max_workqueue=10): + def __init__(self, coin, url, max_workqueue=10): self.coin = coin self.logger = class_logger(__name__, self.__class__.__name__) - self.set_urls(coin.daemon_urls(urls)) + self.set_url(url) self._height = None # Limit concurrent RPC calls to this number. # See DEFAULT_HTTP_WORKQUEUE in bitcoind, which is typically 16 self.workqueue_semaphore = asyncio.Semaphore(value=max_workqueue) self.available_rpcs = {} - def set_urls(self, urls): + def set_url(self, url): '''Set the URLS to the given list, and switch to the first one.''' - if not urls: - raise DaemonError('no daemon URLs provided') - self.urls = urls - self.url_index = 0 + urls = url.split(',') + urls = [self.coin.sanitize_url(url) for url in urls] for n, url in enumerate(urls): status = '' if n else ' (current)' logged_url = self.logged_url(url) self.logger.info(f'daemon #{n + 1} at {logged_url}{status}') + self.url_index = 0 + self.urls = urls - def url(self): + def current_url(self): '''Returns the current daemon URL.''' return self.urls[self.url_index] + def logged_url(self, url=None): + '''The host and port part, for logging.''' + url = url or self.current_url() + return url[url.rindex('@') + 1:] + def failover(self): '''Call to fail-over to the next daemon URL. @@ -81,7 +86,7 @@ class Daemon(object): async def _send_data(self, data): async with self.workqueue_semaphore: async with self.client_session() as session: - async with session.post(self.url(), data=data) as resp: + async with session.post(self.current_url(), data=data) as resp: # If bitcoind can't find a tx, for some reason # it returns 500 but fills out the JSON. # Should still return 200 IMO. @@ -139,11 +144,6 @@ class Daemon(object): await asyncio.sleep(secs) secs = min(max_secs, secs * 2, 1) - def logged_url(self, url=None): - '''The host and port part, for logging.''' - url = url or self.url() - return url[url.rindex('@') + 1:] - async def _send_single(self, method, params=None): '''Send a single request to the daemon.''' def processor(result): diff --git a/electrumx/server/session.py b/electrumx/server/session.py index 37290cf..fd19dd4 100644 --- a/electrumx/server/session.py +++ b/electrumx/server/session.py @@ -383,7 +383,7 @@ class SessionManager(object): '''Replace the daemon URL.''' daemon_url = daemon_url or self.env.daemon_url try: - self.daemon.set_urls(self.env.coin.daemon_urls(daemon_url)) + self.daemon.set_url(daemon_url) except Exception as e: raise RPCError(BAD_REQUEST, f'an error occured: {e!r}') return f'now using daemon at {self.daemon.logged_url()}'