From 66fef1aa054766bc36155a5b7fba410ff964cd43 Mon Sep 17 00:00:00 2001 From: Mikko Ohtamaa Date: Sat, 22 Jul 2023 04:10:36 +0300 Subject: [PATCH] Black --- CHANGELOG.md | 4 ++-- eth_defi/chain.py | 5 +++- eth_defi/fallback_provider.py | 41 ++++++++++++--------------------- eth_defi/hotwallet.py | 13 ++++++----- eth_defi/mev_blocker.py | 18 ++++++++------- eth_defi/utils.py | 2 +- tests/test_event_reader.py | 5 +--- tests/test_fallback_provider.py | 10 +++----- tests/test_mev_blocker.py | 19 +++++++-------- 9 files changed, 53 insertions(+), 64 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8f44be2..e71d5587 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # Current -- Add MEV blocking support -- Add JSON-RPC fallback switching +- Add MEV blocking support in the form of `eth_defi.mev_blocker.MEVBlockerProvider` +- Add JSON-RPC fallback switching in the form of `eth_defi.fallback_provider.FallbackProvider` - Add `HotWallet.create_for_testing` # 0.21.8 diff --git a/eth_defi/chain.py b/eth_defi/chain.py index e436d1f0..7b0cb07c 100644 --- a/eth_defi/chain.py +++ b/eth_defi/chain.py @@ -145,7 +145,10 @@ def install_api_call_counter_middleware_on_provider(provider: JSONBaseProvider) api_counter = Counter() def factory(make_request: Callable[[RPCEndpoint, Any], Any], web3: "Web3"): - import ipdb; ipdb.set_trace() + import ipdb + + ipdb.set_trace() + def middleware(method: RPCEndpoint, params: Any) -> Optional[RPCResponse]: api_counter[method] += 1 api_counter["total"] += 1 diff --git a/eth_defi/fallback_provider.py b/eth_defi/fallback_provider.py index 88bb9724..b2830166 100644 --- a/eth_defi/fallback_provider.py +++ b/eth_defi/fallback_provider.py @@ -20,13 +20,11 @@ class FallbackStrategy(enum.Enum): - #: Automatically switch to the next provider on an error #: cycle_on_error = "cycle_on_error" - class FallbackProvider(JSONBaseProvider): """Fall back to the next provder in the list if a JSON-RPC request fails. @@ -42,15 +40,15 @@ class FallbackProvider(JSONBaseProvider): """ def __init__( - self, - providers: List[JSONBaseProvider], - strategy=FallbackStrategy.cycle_on_error, - retryable_exceptions=DEFAULT_RETRYABLE_EXCEPTIONS, - retryable_status_codes=DEFAULT_RETRYABLE_HTTP_STATUS_CODES, - retryable_rpc_error_codes= DEFAULT_RETRYABLE_RPC_ERROR_CODES, - sleep: float = 5.0, - backoff: float = 1.6, - retries: int = 6, + self, + providers: List[JSONBaseProvider], + strategy=FallbackStrategy.cycle_on_error, + retryable_exceptions=DEFAULT_RETRYABLE_EXCEPTIONS, + retryable_status_codes=DEFAULT_RETRYABLE_HTTP_STATUS_CODES, + retryable_rpc_error_codes=DEFAULT_RETRYABLE_RPC_ERROR_CODES, + sleep: float = 5.0, + backoff: float = 1.6, + retries: int = 6, ): """ :param providers: @@ -106,7 +104,6 @@ def make_request(self, method: RPCEndpoint, params: Any) -> RPCResponse: for i in range(self.retries): provider = self.get_provider() try: - # Call the underlying provider val = provider.make_request(method, params) @@ -116,26 +113,18 @@ def make_request(self, method: RPCEndpoint, params: Any) -> RPCResponse: return val except Exception as e: - if is_retryable_http_exception( - e, - retryable_rpc_error_codes=self.retryable_rpc_error_codes, - retryable_status_codes=self.retryable_status_codes, - retryable_exceptions=self.retryable_exceptions, + e, + retryable_rpc_error_codes=self.retryable_rpc_error_codes, + retryable_status_codes=self.retryable_status_codes, + retryable_exceptions=self.retryable_exceptions, ): - old_provider_name = _get_provider_name(provider) self.switch_provider() new_provider_name = _get_provider_name(self.get_provider()) if i < self.retries - 1: - logger.warning( - "Encountered JSON-RPC retryable error %s when calling method %s.\n" - "Switching providers %s -> %s\n" - "Retrying in %f seconds, retry #%d", - e, method, - old_provider_name, new_provider_name, - current_sleep, i) + logger.warning("Encountered JSON-RPC retryable error %s when calling method %s.\n" "Switching providers %s -> %s\n" "Retrying in %f seconds, retry #%d", e, method, old_provider_name, new_provider_name, current_sleep, i) time.sleep(current_sleep) current_sleep *= self.backoff self.retry_count += 1 @@ -155,4 +144,4 @@ def _get_provider_name(provider: JSONBaseProvider) -> str: """ if isinstance(provider, HTTPProvider): return get_url_domain(provider.endpoint_uri) - return str(provider) \ No newline at end of file + return str(provider) diff --git a/eth_defi/hotwallet.py b/eth_defi/hotwallet.py index 931b666a..0bc3a3b3 100644 --- a/eth_defi/hotwallet.py +++ b/eth_defi/hotwallet.py @@ -196,12 +196,13 @@ def create_for_testing(web3: Web3, test_account_n=0, eth_amount=10): """ wallet = HotWallet.from_private_key("0x" + secrets.token_hex(32)) - tx_hash = web3.eth.send_transaction({ - "from": web3.eth.accounts[test_account_n], - "to": wallet.address, - "value": eth_amount*10**18, - }) + tx_hash = web3.eth.send_transaction( + { + "from": web3.eth.accounts[test_account_n], + "to": wallet.address, + "value": eth_amount * 10**18, + } + ) web3.eth.wait_for_transaction_receipt(tx_hash) wallet.sync_nonce(web3) return wallet - diff --git a/eth_defi/mev_blocker.py b/eth_defi/mev_blocker.py index 6bb91c55..37fea249 100644 --- a/eth_defi/mev_blocker.py +++ b/eth_defi/mev_blocker.py @@ -33,10 +33,10 @@ class MEVBlockerProvider(JSONBaseProvider): """ def __init__( - self, - call_provider: JSONBaseProvider, - transact_provivder: JSONBaseProvider, - transact_methods=TRANSACT_METHODS, + self, + call_provider: JSONBaseProvider, + transact_provivder: JSONBaseProvider, + transact_methods=TRANSACT_METHODS, ): super().__init__() self.call_provider = call_provider @@ -44,10 +44,12 @@ def __init__( self.transact_methods = transact_methods #: Keep tabs on how much API traffic we generate through each endpoint - self.provider_counter = Counter({ - "call": 0, - "transact": 0, - }) + self.provider_counter = Counter( + { + "call": 0, + "transact": 0, + } + ) def is_transact_method(self, method: RPCEndpoint) -> bool: """Does this RPC method do a transaction""" diff --git a/eth_defi/utils.py b/eth_defi/utils.py index 18c9ce7c..9afdee6e 100644 --- a/eth_defi/utils.py +++ b/eth_defi/utils.py @@ -134,4 +134,4 @@ def get_url_domain(url: str) -> str: Some services e.g. infura use path as an API key. """ parsed = urlparse(url) - return parsed.hostname \ No newline at end of file + return parsed.hostname diff --git a/tests/test_event_reader.py b/tests/test_event_reader.py index caa10859..3a71fffc 100644 --- a/tests/test_event_reader.py +++ b/tests/test_event_reader.py @@ -157,11 +157,8 @@ def test_read_events_concurrent_two_blocks_concurrent(web3): assert max(blocks) == 37898276 - def test_read_events_lazy_timestamp(web3): - """Read events but extract timestamps only for events, not whole block ranges. - - """ + """Read events but extract timestamps only for events, not whole block ranges.""" # Get contracts Pair = get_contract(web3, "sushi/UniswapV2Pair.json") diff --git a/tests/test_fallback_provider.py b/tests/test_fallback_provider.py index b1344986..af709676 100644 --- a/tests/test_fallback_provider.py +++ b/tests/test_fallback_provider.py @@ -41,7 +41,7 @@ def fallback_provider(provider_1, provider_2) -> FallbackProvider: def test_fallback_no_issue(fallback_provider: FallbackProvider): - """Callback goes through the first provider """ + """Callback goes through the first provider""" web3 = Web3(fallback_provider) assert fallback_provider.api_call_counts[0]["eth_blockNumber"] == 0 assert fallback_provider.api_call_counts[1]["eth_blockNumber"] == 0 @@ -70,9 +70,7 @@ def test_fallback_double_fault(fallback_provider: FallbackProvider, provider_1, web3 = Web3(fallback_provider) - with patch.object(provider_1, "make_request", side_effect=requests.exceptions.ConnectionError), \ - patch.object(provider_2, "make_request", side_effect=requests.exceptions.ConnectionError): - + with patch.object(provider_1, "make_request", side_effect=requests.exceptions.ConnectionError), patch.object(provider_2, "make_request", side_effect=requests.exceptions.ConnectionError): with pytest.raises(requests.exceptions.ConnectionError): web3.eth.block_number @@ -93,9 +91,7 @@ def borg_start(*args, **kwargs): raise requests.exceptions.ConnectionError() return DEFAULT - with patch.object(provider_1, "make_request", side_effect=borg_start), \ - patch.object(provider_2, "make_request", side_effect=borg_start): - + with patch.object(provider_1, "make_request", side_effect=borg_start), patch.object(provider_2, "make_request", side_effect=borg_start): web3.eth.block_number assert fallback_provider.api_call_counts[0]["eth_blockNumber"] == 1 diff --git a/tests/test_mev_blocker.py b/tests/test_mev_blocker.py index 472b1e49..aacb50f4 100644 --- a/tests/test_mev_blocker.py +++ b/tests/test_mev_blocker.py @@ -13,8 +13,7 @@ @pytest.fixture(scope="session") def anvil() -> AnvilLaunch: """Launch Anvil for the test backend.""" - anvil = launch_anvil( - ) + anvil = launch_anvil() try: yield anvil finally: @@ -57,13 +56,15 @@ def test_mev_blocker_send_transaction_raw(mev_blocker_provider: MEVBlockerProvid web3 = Web3(mev_blocker_provider) wallet = HotWallet.create_for_testing(web3) - signed_tx = wallet.sign_transaction_with_new_nonce({ - "from": wallet.address, - "to": ZERO_ADDRESS, - "value": 1, - "gas": 100_000, - "gasPrice": web3.eth.gas_price, - }) + signed_tx = wallet.sign_transaction_with_new_nonce( + { + "from": wallet.address, + "to": ZERO_ADDRESS, + "value": 1, + "gas": 100_000, + "gasPrice": web3.eth.gas_price, + } + ) # Account for setup API counts from create_for_testing() assert mev_blocker_provider.provider_counter["call"] == 10