From 1f49bf15288d2f38ec58e510b2a0170429dcc55c Mon Sep 17 00:00:00 2001 From: Ortis Date: Tue, 13 Jun 2023 21:48:00 +0900 Subject: [PATCH] W3Pool.use_specific() --- src/w3multicall/multicall.py | 8 ++++---- src/w3multicall/web3/web3.py | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/w3multicall/multicall.py b/src/w3multicall/multicall.py index 3d468f1..dea7346 100644 --- a/src/w3multicall/multicall.py +++ b/src/w3multicall/multicall.py @@ -128,13 +128,13 @@ def __init__(self, address: str, signature: str, args=None): self.selector = eth_utils.function_signature_to_4byte_selector(self.name) self.data = _encode_data(self.selector, self.input_types, self.args) - def __init__(self, w3, address='0xcA11bde05977b3631167028862bE2a173976CA11', calls: List['W3Multicall.Call'] = None): + def __init__(self, web3, address='0xcA11bde05977b3631167028862bE2a173976CA11', calls: List['W3Multicall.Call'] = None): """ - :param w3: Web3 instance + :param web3: Web3 instance :param address: (optional) address of the multicall3.sol contract :param calls: (optional) list of W3Multicall.Call to perform """ - self.w3 = w3 + self.web3 = web3 self.address = address self.calls: List['W3Multicall.Call'] = [] if calls is None else calls.copy() self.require_success = True @@ -149,7 +149,7 @@ def call(self) -> list: 'to': self.address, 'data': data } - rpc_response = self.w3.eth.call(eth_call_params) + rpc_response = self.web3.eth.call(eth_call_params) aggregated = _decode_output(rpc_response, W3Multicall.MULTICALL_OUTPUT_TYPES) unpacked = _unpack_aggregate_outputs(aggregated[1]) outputs = [] diff --git a/src/w3multicall/web3/web3.py b/src/w3multicall/web3/web3.py index 10b71ff..9f290cd 100644 --- a/src/w3multicall/web3/web3.py +++ b/src/w3multicall/web3/web3.py @@ -46,6 +46,29 @@ def add_w3(self, w3: W3) -> 'W3Pool': self.w3s.append(w3) return self + def use_specific(self, w3_target: Union[W3, str], block: bool = True): + while True: + target = None + with self.lock: + for i in range(len(self.w3s)): + if self.w3s[i] == w3_target or self.w3s[i].label == w3_target: + tau = self.w3s[i].usable_in() + if tau <= 0: + if self.logger is not None: + self.logger.debug("Using {}".format(self.w3s[i])) + return self.w3s[i].use() + target = self.w3s[i] + break + + if target is None: + raise Exception("Target w3 '{}' not found".format(w3_target)) + if block: + sleep = target.usable_in() + if sleep > 0: + if self.logger is not None: + self.logger.warning("Waiting {}s for {}".format(sleep, target)) + time.sleep(sleep) + def use(self, block: bool = True) -> Union[Web3, None]: """ Return a Web3 instance that will not hit the rate limit upon calling (may block until the rate limit windows has passed)