From 5a548e00727c825aff7e6d183456eda68c7ea482 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Paw=C5=82owski?= <43270043+PawlowskiAdrian@users.noreply.github.com> Date: Wed, 28 Sep 2022 09:28:43 +0200 Subject: [PATCH 1/4] Update uniswap.py enable caching, will reduce RPC calls for method chainID --- uniswap/uniswap.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/uniswap/uniswap.py b/uniswap/uniswap.py index ae5ad16..2f89b58 100644 --- a/uniswap/uniswap.py +++ b/uniswap/uniswap.py @@ -8,6 +8,7 @@ from web3 import Web3 from web3._utils.abi import map_abi_data from web3._utils.normalizers import BASE_RETURN_NORMALIZERS +from web3.middleware import simple_cache_middleware from web3.contract import Contract, ContractFunction from web3.exceptions import BadFunctionCallOutput, ContractLogicError from web3.types import ( @@ -115,7 +116,7 @@ def __init__( provider = os.environ["PROVIDER"] self.w3 = Web3(Web3.HTTPProvider(provider, request_kwargs={"timeout": 60})) - # Cache netid to avoid extra RPC calls + self.w3.middleware_onion.inject(simple_cache_middleware, layer=0) self.netid = int(self.w3.net.version) if self.netid in _netid_to_name: self.netname = _netid_to_name[self.netid] From ee5b84c34a2f04ba443a6668989fd49b04f92524 Mon Sep 17 00:00:00 2001 From: PawlowskiAdrian Date: Wed, 28 Sep 2022 10:46:14 +0200 Subject: [PATCH 2/4] custom simple middleware with - custom eth caching middleware creation - custom SIMPLE_CACHE_RPC_WHITELIST - flag to enable/disable caching for class Uniswap --- uniswap/constants.py | 14 ++++++++++++++ uniswap/uniswap.py | 8 ++++++-- uniswap/util.py | 15 +++++++++++++-- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/uniswap/constants.py b/uniswap/constants.py index 60fd4c3..58b4522 100644 --- a/uniswap/constants.py +++ b/uniswap/constants.py @@ -1,3 +1,17 @@ +from typing import Set, cast +from web3.types import ( # noqa: F401 + RPCEndpoint, +) + +# look at web3/middleware/cache.py for reference +# RPC methods that will be cached inside _get_eth_simple_cache_middleware +SIMPLE_CACHE_RPC_WHITELIST = cast( + Set[RPCEndpoint], + { + "eth_chainId", + }, +) + ETH_ADDRESS = "0x0000000000000000000000000000000000000000" WETH9_ADDRESS = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" diff --git a/uniswap/uniswap.py b/uniswap/uniswap.py index 2f89b58..3b8b3a2 100644 --- a/uniswap/uniswap.py +++ b/uniswap/uniswap.py @@ -8,7 +8,6 @@ from web3 import Web3 from web3._utils.abi import map_abi_data from web3._utils.normalizers import BASE_RETURN_NORMALIZERS -from web3.middleware import simple_cache_middleware from web3.contract import Contract, ContractFunction from web3.exceptions import BadFunctionCallOutput, ContractLogicError from web3.types import ( @@ -24,6 +23,7 @@ from .token import ERC20Token from .exceptions import InvalidToken, InsufficientBalance from .util import ( + _get_eth_simple_cache_middleware, _str_to_addr, _addr_to_str, _validate_address, @@ -79,6 +79,7 @@ def __init__( # use_eip1559: bool = True, factory_contract_addr: str = None, router_contract_addr: str = None, + enable_caching: bool = False, ) -> None: """ :param address: The public address of the ETH wallet to use. @@ -89,6 +90,7 @@ def __init__( :param default_slippage: Default slippage for a trade, as a float (0.01 is 1%). WARNING: slippage is untested. :param factory_contract_addr: Can be optionally set to override the address of the factory contract. :param router_contract_addr: Can be optionally set to override the address of the router contract (v2 only). + :param enable_caching: Optionally enables middleware caching RPC method calls. """ self.address = _str_to_addr( address or "0x0000000000000000000000000000000000000000" @@ -116,7 +118,9 @@ def __init__( provider = os.environ["PROVIDER"] self.w3 = Web3(Web3.HTTPProvider(provider, request_kwargs={"timeout": 60})) - self.w3.middleware_onion.inject(simple_cache_middleware, layer=0) + if enable_caching == True: + self.w3.middleware_onion.inject(_get_eth_simple_cache_middleware, layer=0) + self.netid = int(self.w3.net.version) if self.netid in _netid_to_name: self.netname = _netid_to_name[self.netid] diff --git a/uniswap/util.py b/uniswap/util.py index 2f65ab2..6826812 100644 --- a/uniswap/util.py +++ b/uniswap/util.py @@ -2,16 +2,27 @@ import json import math import functools -from typing import Any, Generator, Sequence, Union, List, Tuple +import lru + +from typing import Any, Generator, Sequence, Union, List, Tuple, Type, Dict, cast from web3 import Web3 from web3.exceptions import NameNotFound from web3.contract import Contract +from web3.middleware.cache import construct_simple_cache_middleware +from web3.types import Middleware -from .constants import MIN_TICK, MAX_TICK, _tick_spacing +from .constants import MIN_TICK, MAX_TICK, _tick_spacing, SIMPLE_CACHE_RPC_WHITELIST from .types import AddressLike, Address +def _get_eth_simple_cache_middleware() -> Middleware: + return construct_simple_cache_middleware( + cache_class=cast(Type[Dict[Any, Any]], functools.partial(lru.LRU, 256)), + rpc_whitelist=SIMPLE_CACHE_RPC_WHITELIST, + ) + + def _str_to_addr(s: Union[AddressLike, str]) -> Address: """Idempotent""" if isinstance(s, str): From cf11989e991cffe6bd45880a91fa055d12077380 Mon Sep 17 00:00:00 2001 From: PawlowskiAdrian Date: Wed, 28 Sep 2022 10:49:55 +0200 Subject: [PATCH 3/4] fix typo --- uniswap/uniswap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uniswap/uniswap.py b/uniswap/uniswap.py index 3b8b3a2..673ad52 100644 --- a/uniswap/uniswap.py +++ b/uniswap/uniswap.py @@ -119,7 +119,7 @@ def __init__( self.w3 = Web3(Web3.HTTPProvider(provider, request_kwargs={"timeout": 60})) if enable_caching == True: - self.w3.middleware_onion.inject(_get_eth_simple_cache_middleware, layer=0) + self.w3.middleware_onion.inject(_get_eth_simple_cache_middleware(), layer=0) self.netid = int(self.w3.net.version) if self.netid in _netid_to_name: From bd1f1682cef535b0e0689aae84821217d7f39055 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Bj=C3=A4reholt?= Date: Wed, 12 Oct 2022 17:21:43 +0200 Subject: [PATCH 4/4] style: don't compare with True --- uniswap/uniswap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uniswap/uniswap.py b/uniswap/uniswap.py index 673ad52..8660f2d 100644 --- a/uniswap/uniswap.py +++ b/uniswap/uniswap.py @@ -118,7 +118,7 @@ def __init__( provider = os.environ["PROVIDER"] self.w3 = Web3(Web3.HTTPProvider(provider, request_kwargs={"timeout": 60})) - if enable_caching == True: + if enable_caching: self.w3.middleware_onion.inject(_get_eth_simple_cache_middleware(), layer=0) self.netid = int(self.w3.net.version)