-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7c427d2
commit 50b3305
Showing
8 changed files
with
686 additions
and
320 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
from importlib.metadata import version | ||
from typing import Tuple, Type | ||
|
||
from typing_extensions import Self | ||
from web3.eth import BaseEth | ||
from web3._utils.method_formatters import ERROR_FORMATTERS, NULL_RESULT_FORMATTERS | ||
from web3._utils.blocks import select_method_for_block_identifier | ||
from web3._utils.rpc_abi import RPC | ||
from web3.method import Method, TFunc, _apply_request_formatters, default_root_munger | ||
from web3.types import BlockIdentifier | ||
|
||
|
||
WEB3_MAJOR_VERSION = int(version("web3").split(".")[0]) | ||
|
||
return_as_is = lambda x: x | ||
|
||
|
||
class MethodNoFormat(Method[TFunc]): | ||
"""Bypasses web3py default result formatters.""" | ||
|
||
def process_params(self, module, *args, **kwargs): | ||
params = self.input_munger(module, args, kwargs) | ||
|
||
if self.method_choice_depends_on_args: | ||
# If the method choice depends on the args that get passed in, | ||
# the first parameter determines which method needs to be called | ||
self.json_rpc_method = self.method_choice_depends_on_args(value=params[0]) | ||
|
||
pending_or_latest_filter_methods = [ | ||
RPC.eth_newPendingTransactionFilter, | ||
RPC.eth_newBlockFilter, | ||
] | ||
if self.json_rpc_method in pending_or_latest_filter_methods: | ||
# For pending or latest filter methods, use params to determine | ||
# which method to call, but don't pass them through with the request | ||
params = [] | ||
|
||
method = self.method_selector_fn() | ||
request = (method, _apply_request_formatters(params, self.request_formatters(method))) | ||
response_formatters = ( | ||
return_as_is, | ||
ERROR_FORMATTERS.get(self.json_rpc_method, return_as_is), # type: ignore [arg-type] | ||
NULL_RESULT_FORMATTERS.get(self.json_rpc_method, return_as_is), # type: ignore [arg-type] | ||
) | ||
return request, response_formatters | ||
|
||
@classmethod | ||
def default(cls, method: RPC) -> Self: | ||
return cls(method, [default_root_munger]) | ||
|
||
|
||
def bypass_chainid_formatter(eth: Type[BaseEth]) -> None: | ||
eth._chain_id = MethodNoFormat(RPC.eth_chainId) | ||
|
||
|
||
def bypass_getbalance_formatter(eth: Type[BaseEth]) -> None: | ||
eth._get_balance = MethodNoFormat(RPC.eth_getBalance, mungers=[eth.block_id_munger]) | ||
|
||
|
||
def bypass_blocknumber_formatter(eth: Type[BaseEth]) -> None: | ||
eth.get_block_number = MethodNoFormat(RPC.eth_blockNumber) | ||
|
||
|
||
def bypass_transaction_count_formatter(eth: Type[BaseEth]) -> None: | ||
eth._get_transaction_count = MethodNoFormat( | ||
RPC.eth_getTransactionCount, mungers=[eth.block_id_munger] | ||
) | ||
|
||
|
||
def bypass_log_formatter(eth: Type[BaseEth]) -> None: | ||
eth._get_logs = MethodNoFormat.default(RPC.eth_getLogs) | ||
eth._get_logs_raw = MethodNoFormat.default(f"{RPC.eth_getLogs}_raw") | ||
eth.get_filter_logs = MethodNoFormat.default(RPC.eth_getFilterLogs) | ||
eth.get_filter_changes = MethodNoFormat.default(RPC.eth_getFilterChanges) | ||
|
||
|
||
def bypass_transaction_receipt_formatter(eth: Type[BaseEth]) -> None: | ||
attr_name = "_transaction_receipt" if WEB3_MAJOR_VERSION >= 6 else "_get_transaction_receipt" | ||
setattr(eth, attr_name, MethodNoFormat.default(RPC.eth_getTransactionReceipt)) | ||
|
||
|
||
def bypass_transaction_formatter(eth: Type[BaseEth]) -> None: | ||
eth._get_transaction = MethodNoFormat.default(RPC.eth_getTransactionByHash) | ||
|
||
|
||
_block_selectors = dict( | ||
if_predefined=RPC.eth_getBlockByNumber, | ||
if_hash=RPC.eth_getBlockByHash, | ||
if_number=RPC.eth_getBlockByNumber, | ||
) | ||
|
||
|
||
def bypass_block_formatters(eth: Type[BaseEth]) -> None: | ||
if WEB3_MAJOR_VERSION >= 6: | ||
get_block_munger = eth.get_block_munger | ||
else: | ||
|
||
def get_block_munger( | ||
self, block_identifier: BlockIdentifier, full_transactions: bool = False | ||
) -> Tuple[BlockIdentifier, bool]: | ||
return (block_identifier, full_transactions) | ||
|
||
eth._get_block = MethodNoFormat( | ||
method_choice_depends_on_args=select_method_for_block_identifier(**_block_selectors), | ||
mungers=[get_block_munger], | ||
) | ||
|
||
|
||
def bypass_eth_call_formatter(eth: Type[BaseEth]) -> None: | ||
eth._call = MethodNoFormat(RPC.eth_call, mungers=[eth.call_munger]) | ||
|
||
|
||
def bypass_get_code_formatter(eth: Type[BaseEth]) -> None: | ||
eth._get_code = MethodNoFormat(RPC.eth_getCode, mungers=[eth.block_id_munger]) | ||
|
||
|
||
skip_formatters = ( | ||
bypass_chainid_formatter, | ||
bypass_getbalance_formatter, | ||
bypass_blocknumber_formatter, | ||
bypass_transaction_count_formatter, | ||
bypass_eth_call_formatter, | ||
bypass_get_code_formatter, | ||
bypass_log_formatter, | ||
bypass_transaction_receipt_formatter, | ||
bypass_transaction_formatter, | ||
bypass_block_formatters, | ||
) | ||
|
||
|
||
def bypass_formatters(eth): | ||
for bypass in skip_formatters: | ||
bypass(eth) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.