diff --git a/moonworm/cli.py b/moonworm/cli.py index dfc6739..b367783 100644 --- a/moonworm/cli.py +++ b/moonworm/cli.py @@ -172,7 +172,7 @@ def handle_watch(args: argparse.Namespace) -> None: watch_contract( web3=web3, state_provider=state_provider, - contract_address=web3.toChecksumAddress(args.contract), + contract_address=web3.to_checksum_address(args.contract), contract_abi=contract_abi, num_confirmations=args.confirmations, start_block=args.start, @@ -186,7 +186,7 @@ def handle_watch(args: argparse.Namespace) -> None: watch_contract( web3=web3, state_provider=Web3StateProvider(web3), - contract_address=web3.toChecksumAddress(args.contract), + contract_address=web3.to_checksum_address(args.contract), contract_abi=contract_abi, num_confirmations=args.confirmations, start_block=args.start, @@ -418,7 +418,7 @@ def generate_argument_parser() -> argparse.ArgumentParser: find_deployment_parser.add_argument( "-c", "--contract", - type=Web3.toChecksumAddress, + type=Web3.to_checksum_address, required=True, help="Contract address", ) diff --git a/moonworm/crawler/ethereum_state_provider.py b/moonworm/crawler/ethereum_state_provider.py index c584074..675e6a5 100644 --- a/moonworm/crawler/ethereum_state_provider.py +++ b/moonworm/crawler/ethereum_state_provider.py @@ -62,7 +62,7 @@ class Web3StateProvider(EthereumStateProvider): def _get_block(self, block_number: int) -> Dict[str, Any]: if block_number in self.blocks_cache: return self.blocks_cache[block_number] - block = self.w3.eth.getBlock(block_number, full_transactions=True) + block = self.w3.eth.get_block(block_number, full_transactions=True) # clear cache if it grows too large if len(self.blocks_cache) > 50: diff --git a/moonworm/crawler/function_call_crawler.py b/moonworm/crawler/function_call_crawler.py index 2ac2f3d..b393563 100644 --- a/moonworm/crawler/function_call_crawler.py +++ b/moonworm/crawler/function_call_crawler.py @@ -111,7 +111,7 @@ def utfy_dict(dic): return dic elif isinstance(dic, bytes): - return Web3.toHex(dic) + return Web3.to_hex(dic) elif isinstance(dic, tuple): return tuple(utfy_dict(x) for x in dic) @@ -148,7 +148,7 @@ class FunctionCallCrawler: self.contract = Web3().eth.contract(abi=self.contract_abi) self.on_decode_error = on_decode_error self.whitelisted_methods = { - Web3.toHex(function_abi_to_4byte_selector(a)) for a in self.contract_abi + Web3.to_hex(function_abi_to_4byte_selector(a)) for a in self.contract_abi } def process_transaction(self, transaction: Dict[str, Any]): diff --git a/moonworm/crawler/log_scanner.py b/moonworm/crawler/log_scanner.py index 7982770..3cd9a04 100644 --- a/moonworm/crawler/log_scanner.py +++ b/moonworm/crawler/log_scanner.py @@ -3,7 +3,8 @@ import datetime import json import logging import time -from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple +from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, Union +import traceback from eth_abi.codec import ABICodec from eth_typing.evm import ChecksumAddress @@ -113,7 +114,7 @@ def _fetch_events_chunk( raw_event = get_event_data(codec, event_abi, log) event = { "event": raw_event["event"], - "args": json.loads(Web3.toJSON(utfy_dict(dict(raw_event["args"])))), + "args": json.loads(Web3.to_json(utfy_dict(dict(raw_event["args"])))), "address": raw_event["address"], "blockNumber": raw_event["blockNumber"], "transactionHash": raw_event["transactionHash"].hex(), @@ -195,7 +196,7 @@ class EventScanner: self.checksum_addresses = [] if addresses: for address in addresses: - self.checksum_addresses.append(web3.toChecksumAddress(address)) + self.checksum_addresses.append(web3.to_checksum_address(address)) # Our JSON-RPC throttling parameters self.min_scan_chunk_size = 10 # 12 s/block = 120 seconds period @@ -216,7 +217,7 @@ class EventScanner: # Returning None since, config set to skip getting block timestamp data return None try: - block_info = self.web3.eth.getBlock(block_num) + block_info = self.web3.eth.get_block(block_num) except BlockNotFound: # Block was not mined yet, # minor chain reorganisation? @@ -247,13 +248,24 @@ class EventScanner: return self.web3.eth.blockNumber - 1 def get_last_scanned_block(self) -> int: + """Get the last scanned block number.""" + + if self.state is None: + return 0 + return self.state.get_last_scanned_block() def delete_potentially_forked_block_data(self, after_block: int): """Purge old data in the case of blockchain reorganisation.""" + + if self.state is None: + return + self.state.delete_data(after_block) - def estimate_next_chunk_size(self, current_chuck_size: int, event_found_count: int): + def estimate_next_chunk_size( + self, current_chuck_size: Union[int, float], event_found_count: int + ): """Try to figure out optimal chunk size Our scanner might need to scan the whole blockchain for all events @@ -343,6 +355,8 @@ class EventScanner: evt["event"], evt["blockNumber"], ) + if self.state is None: + raise Exception("State is not initialized") processed = self.state.process_event(block_when, evt) all_processed.append(processed) @@ -377,14 +391,16 @@ class EventScanner: # Scan in chunks, commit between chunk_size = start_chunk_size - last_scan_duration = last_logs_found = 0 + last_scan_duration = last_logs_found = 0.0 total_chunks_scanned = 0 # All processed entries we got on this scan cycle all_processed = [] while current_block <= end_block: - self.state.start_chunk(current_block, chunk_size) + if self.state is None: + raise Exception("State is not initialized") + self.state.start_chunk(current_block, chunk_size) # type: ignore # Print some diagnostics to logs to try to fiddle with real world JSON-RPC API performance estimated_end_block = current_block + chunk_size diff --git a/moonworm/crawler/moonstream_ethereum_state_provider.py b/moonworm/crawler/moonstream_ethereum_state_provider.py index 620c047..7875c95 100644 --- a/moonworm/crawler/moonstream_ethereum_state_provider.py +++ b/moonworm/crawler/moonstream_ethereum_state_provider.py @@ -149,7 +149,7 @@ class MoonstreamEthereumStateProvider(EthereumStateProvider): block = self._get_block_from_db(block_number) if block is None: logger.debug(f"{log_prefix} - not found in db or cache, fetching from web3") - block = self.w3.eth.getBlock(block_number, full_transactions=True) + block = self.w3.eth.get_block(block_number, full_transactions=True) self.metrics["web3_get_block_calls"] += 1 else: logger.debug(f"{log_prefix} - found in db") diff --git a/moonworm/generators/cli.py.template b/moonworm/generators/cli.py.template index c13a50a..8270c42 100644 --- a/moonworm/generators/cli.py.template +++ b/moonworm/generators/cli.py.template @@ -33,7 +33,7 @@ def init_web3(ipc_path: str) -> Web3: def init_contract(web3: Web3, abi: Dict[str, Any], address: Optional[str]) -> Contract: checksum_address: Optional[ChecksumAddress] = None if address is not None: - checksum_address = web3.toChecksumAddress(address) + checksum_address = web3.to_checksum_address(address) return web3.eth.contract(address=checksum_address, abi=abi) def make_function_call(contract: Contract, function_name: str, *args): @@ -102,7 +102,7 @@ def handle_args(args: argparse.Namespace): if args.contract_address is None: print("Contract address was not passed from arguments") args.contract_address = input("Enter contract address you want to call: ") - contract_address = web3.toChecksumAddress(args.contract_address) + contract_address = web3.to_checksum_address(args.contract_address) contract = web3.eth.contract(address=contract_address, abi=CONTRACT_ABI) function_name = kwargs["function_name"] del kwargs["function_name"] @@ -116,7 +116,7 @@ def handle_args(args: argparse.Namespace): if args.contract_address is None: print("Contract address was not passed from arguments") args.contract_address = input("Enter contract address you want to transact: ") - contract_address = web3.toChecksumAddress(args.contract_address) + contract_address = web3.to_checksum_address(args.contract_address) contract = web3.eth.contract(address=contract_address, abi=CONTRACT_ABI) function_name = kwargs["function_name"] del kwargs["function_name"] @@ -153,7 +153,7 @@ def handle_args(args: argparse.Namespace): deployer_private_key=pk, constructor_arguments=constructor_args, ) - print(f"Tx hash of deployment: {{web3.toHex(tx_hash)}}") + print(f"Tx hash of deployment: {{web3.to_hex(tx_hash)}}") print(f"Address of deployed_contract: {{contract_address}}") def main() -> None: diff --git a/moonworm/generators/contract.py.template b/moonworm/generators/contract.py.template index 6a6bda2..5e68536 100644 --- a/moonworm/generators/contract.py.template +++ b/moonworm/generators/contract.py.template @@ -6,7 +6,7 @@ from typing import Any, Dict, Union from eth_typing.evm import Address, ChecksumAddress from web3 import Web3 -from web3.contract import ContractFunction +from web3.contract.contract import ContractFunction from .web3_util import * diff --git a/moonworm/version.py b/moonworm/version.py index af16777..2709226 100644 --- a/moonworm/version.py +++ b/moonworm/version.py @@ -1 +1 @@ -MOONWORM_VERSION = "0.6.2" +MOONWORM_VERSION = "0.7.0" diff --git a/moonworm/watch.py b/moonworm/watch.py index dd2f163..7009099 100644 --- a/moonworm/watch.py +++ b/moonworm/watch.py @@ -119,13 +119,13 @@ def watch_contract( state, state_provider, contract_abi, - [web3.toChecksumAddress(contract_address)], + [web3.to_checksum_address(contract_address)], ) event_abis = [item for item in contract_abi if item["type"] == "event"] if start_block is None: - current_block = web3.eth.blockNumber - num_confirmations * 2 + current_block = web3.eth.block_number - num_confirmations * 2 else: current_block = start_block @@ -139,7 +139,7 @@ def watch_contract( while end_block is None or current_block <= end_block: time.sleep(sleep_time) until_block = min( - web3.eth.blockNumber - num_confirmations, + web3.eth.block_number - num_confirmations, current_block + current_batch_size, ) if end_block is not None: diff --git a/moonworm/web3_util.py b/moonworm/web3_util.py index f777da2..45235cf 100644 --- a/moonworm/web3_util.py +++ b/moonworm/web3_util.py @@ -7,7 +7,8 @@ from eth_account.account import Account # type: ignore from eth_typing.evm import ChecksumAddress from hexbytes.main import HexBytes from web3 import Web3 -from web3.contract import Contract, ContractFunction +from web3.contract import Contract +from web3.contract.contract import ContractFunction from web3.providers.ipc import IPCProvider from web3.providers.rpc import HTTPProvider from web3.types import ABI, Nonce, TxParams, TxReceipt, Wei @@ -33,7 +34,7 @@ def build_transaction( - maxPriorityFeePerGas: Optional the part of the fee that goes to the miner """ - transaction = builder.buildTransaction( + transaction = builder.build_transaction( { "from": sender, "nonce": get_nonce(web3, sender), @@ -105,7 +106,7 @@ def deploy_contract( transaction_hash = submit_transaction(web3, transaction, deployer_private_key) transaction_receipt = wait_for_transaction_receipt(web3, transaction_hash) contract_address = transaction_receipt.contractAddress - return transaction_hash, web3.toChecksumAddress(contract_address) + return transaction_hash, web3.to_checksum_address(contract_address) def deploy_contract_from_constructor_function( @@ -134,7 +135,7 @@ def deploy_contract_from_constructor_function( transaction_hash = submit_transaction(web3, transaction, deployer_private_key) transaction_receipt = wait_for_transaction_receipt(web3, transaction_hash) contract_address = transaction_receipt.contractAddress - return transaction_hash, web3.toChecksumAddress(contract_address) + return transaction_hash, web3.to_checksum_address(contract_address) def decode_transaction_input(web3: Web3, transaction_input: str, abi: Dict[str, Any]): @@ -145,7 +146,7 @@ def decode_transaction_input(web3: Web3, transaction_input: str, abi: Dict[str, def read_keys_from_cli() -> Tuple[ChecksumAddress, str]: private_key = getpass.getpass(prompt="Enter private key of your address:") account = Account.from_key(private_key) - return (Web3.toChecksumAddress(account.address), private_key) + return (Web3.to_checksum_address(account.address), private_key) def read_keys_from_env() -> Tuple[ChecksumAddress, str]: @@ -156,7 +157,7 @@ def read_keys_from_env() -> Tuple[ChecksumAddress, str]: ) try: account = Account.from_key(private_key) - return (Web3.toChecksumAddress(account.address), private_key) + return (Web3.to_checksum_address(account.address), private_key) except: raise ValueError( "Failed to initiate account from MOONWORM_ETHEREUM_ADDRESS_PRIVATE_KEY" @@ -193,7 +194,7 @@ def cast_to_python_type(evm_type: str) -> Callable: elif evm_type == "string": return str elif evm_type == "address": - return Web3.toChecksumAddress + return Web3.to_checksum_address elif evm_type == "bool": return bool else: diff --git a/setup.py b/setup.py index 8f35043..f73a26d 100644 --- a/setup.py +++ b/setup.py @@ -18,7 +18,7 @@ setup( "pysha3<2.0.0,>=1.0.0", "tqdm", "typing-extensions", - "web3>=5.27.0", + "web3>=6.1.0", ], extras_require={ "dev": ["isort", "mypy", "wheel", "web3>=5.27.0"],