From ba8a613d7e9311f708c4be6d7541a864734ae867 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ux=C3=ADo?= Date: Thu, 14 Mar 2024 11:03:11 +0100 Subject: [PATCH] Refactor UserOperationReceipt into dataclass (#831) - That way we can add custom methods - Add new methods for UserOperationReceipt - Calculate deposit to the entrypoint - Get Safe module address used --- gnosis/eth/account_abstraction/__init__.py | 3 +- .../eth/account_abstraction/bundler_client.py | 35 +- gnosis/eth/account_abstraction/constants.py | 13 + .../eth/account_abstraction/user_operation.py | 19 +- .../user_operation_receipt.py | 74 ++++ .../test_bundler_client.py | 16 +- .../test_e2e_bundler_client.py | 15 +- .../test_user_operation.py | 4 +- .../test_user_operation_receipt.py | 22 ++ gnosis/eth/tests/mocks/mock_bundler.py | 344 ------------------ 10 files changed, 163 insertions(+), 382 deletions(-) create mode 100644 gnosis/eth/account_abstraction/constants.py create mode 100644 gnosis/eth/account_abstraction/user_operation_receipt.py create mode 100644 gnosis/eth/tests/account_abstraction/test_user_operation_receipt.py diff --git a/gnosis/eth/account_abstraction/__init__.py b/gnosis/eth/account_abstraction/__init__.py index 8174e361d..a6479f6eb 100644 --- a/gnosis/eth/account_abstraction/__init__.py +++ b/gnosis/eth/account_abstraction/__init__.py @@ -8,4 +8,5 @@ BundlerClientException, BundlerClientResponseException, ) -from .user_operation import UserOperation, UserOperationMetadata, UserOperationReceipt +from .user_operation import UserOperation, UserOperationMetadata +from .user_operation_receipt import UserOperationReceipt diff --git a/gnosis/eth/account_abstraction/bundler_client.py b/gnosis/eth/account_abstraction/bundler_client.py index 46fa7c7e3..11f931286 100644 --- a/gnosis/eth/account_abstraction/bundler_client.py +++ b/gnosis/eth/account_abstraction/bundler_client.py @@ -3,11 +3,13 @@ from typing import Any, Dict, List, Optional, Sequence, Tuple, Union from eth_typing import ChecksumAddress, HexStr +from hexbytes import HexBytes from gnosis.util.http import prepare_http_session from .exceptions import BundlerClientConnectionException, BundlerClientResponseException -from .user_operation import UserOperation, UserOperationReceipt +from .user_operation import UserOperation +from .user_operation_receipt import UserOperationReceipt logger = logging.getLogger(__name__) @@ -71,9 +73,18 @@ def _do_request( def _parse_user_operation_receipt( user_operation_receipt: Dict[str, Any] ) -> UserOperationReceipt: - for field in ["nonce", "actualGasCost", "actualGasUsed"]: - user_operation_receipt[field] = int(user_operation_receipt[field], 16) - return user_operation_receipt + return UserOperationReceipt( + HexBytes(user_operation_receipt["userOpHash"]), + user_operation_receipt["entryPoint"], + user_operation_receipt["sender"], + int(user_operation_receipt["nonce"], 16), + user_operation_receipt["paymaster"], + int(user_operation_receipt["actualGasCost"], 16), + int(user_operation_receipt["actualGasUsed"], 16), + user_operation_receipt["success"], + user_operation_receipt["reason"], + user_operation_receipt["logs"], + ) @staticmethod def _get_user_operation_by_hash_payload( @@ -105,7 +116,9 @@ def get_user_operation_by_hash( https://docs.alchemy.com/reference/eth-getuseroperationbyhash :param user_operation_hash: - :return: + :return: ``UserOperation`` or ``None`` if not found + :raises BundlerClientConnectionException: + :raises BundlerClientResponseException: """ payload = self._get_user_operation_by_hash_payload(user_operation_hash) result = self._do_request(payload) @@ -123,11 +136,13 @@ def get_user_operation_receipt( https://docs.alchemy.com/reference/eth-getuseroperationreceipt :param user_operation_hash: - :return: + :return: ``UserOperationReceipt`` or ``None`` if not found + :raises BundlerClientConnectionException: + :raises BundlerClientResponseException: """ payload = self._get_user_operation_receipt_payload(user_operation_hash) result = self._do_request(payload) - return self._parse_user_operation_receipt(result) if result else None + return UserOperationReceipt.from_bundler_response(result) if result else None @lru_cache(maxsize=1024) def get_user_operation_and_receipt( @@ -138,7 +153,9 @@ def get_user_operation_and_receipt( NOTE: Batch requests are not supported by Pimlico :param user_operation_hash: - :return: Tuple with UserOperation and UserOperationReceipt, or None if not found + :return: Tuple with ``UserOperation`` and ``UserOperationReceipt``, or ``None`` if not found + :raises BundlerClientConnectionException: + :raises BundlerClientResponseException: """ payload = [ self._get_user_operation_by_hash_payload(user_operation_hash, request_id=1), @@ -158,6 +175,8 @@ def supported_entry_points(self) -> List[ChecksumAddress]: https://docs.alchemy.com/reference/eth-supportedentrypoints :return: List of supported entrypoints + :raises BundlerClientConnectionException: + :raises BundlerClientResponseException: """ payload = { "jsonrpc": "2.0", diff --git a/gnosis/eth/account_abstraction/constants.py b/gnosis/eth/account_abstraction/constants.py new file mode 100644 index 000000000..98b7d282d --- /dev/null +++ b/gnosis/eth/account_abstraction/constants.py @@ -0,0 +1,13 @@ +from hexbytes import HexBytes + +# Entrypoint v0.6.0 and v0.7.0 deposited event +# Deposited (index_topic_1 address account, uint256 totalDeposit) +DEPOSIT_EVENT_TOPIC = HexBytes( + "0x2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c4" +) + +# Safe > 1.4.1 event +# ExecutionFromModuleSuccess (index_topic_1 address module) +EXECUTION_FROM_MODULE_SUCCESS_TOPIC = HexBytes( + "0x6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb8" +) diff --git a/gnosis/eth/account_abstraction/user_operation.py b/gnosis/eth/account_abstraction/user_operation.py index 4e009f003..76cb35271 100644 --- a/gnosis/eth/account_abstraction/user_operation.py +++ b/gnosis/eth/account_abstraction/user_operation.py @@ -1,6 +1,6 @@ import dataclasses from functools import cached_property -from typing import Any, Dict, List, Optional, TypedDict, Union +from typing import Any, Dict, Optional, Union from eth_abi import encode as abi_encode from eth_typing import ChecksumAddress, HexStr @@ -10,14 +10,14 @@ from gnosis.eth.utils import fast_keccak -@dataclasses.dataclass +@dataclasses.dataclass(eq=True, frozen=True) class UserOperationMetadata: transaction_hash: bytes block_hash: bytes block_number: int -@dataclasses.dataclass +@dataclasses.dataclass(eq=True, frozen=True) class UserOperation: """ EIP4337 UserOperation for Entrypoint v0.6 @@ -117,16 +117,3 @@ def calculate_user_operation_hash(self, chain_id: int) -> bytes: [fast_keccak(user_operation_encoded), self.entry_point, chain_id], ) ) - - -class UserOperationReceipt(TypedDict): - userOpHash: HexStr - entryPoint: HexStr - sender: ChecksumAddress - nonce: int - paymaster: ChecksumAddress - actualGasCost: int - actualGasUsed: int - success: bool - reason: str - logs: List[Dict[str, Any]] diff --git a/gnosis/eth/account_abstraction/user_operation_receipt.py b/gnosis/eth/account_abstraction/user_operation_receipt.py new file mode 100644 index 000000000..2ecaa563e --- /dev/null +++ b/gnosis/eth/account_abstraction/user_operation_receipt.py @@ -0,0 +1,74 @@ +import dataclasses +from typing import Any, Dict, List, Optional + +from eth_typing import ChecksumAddress +from hexbytes import HexBytes +from web3 import Web3 +from web3.types import LogReceipt + +from gnosis.eth.account_abstraction.constants import ( + DEPOSIT_EVENT_TOPIC, + EXECUTION_FROM_MODULE_SUCCESS_TOPIC, +) + + +@dataclasses.dataclass(eq=True, frozen=True) +class UserOperationReceipt: + user_operation_hash: bytes + entry_point: ChecksumAddress + sender: ChecksumAddress + nonce: int + paymaster: ChecksumAddress + actual_gas_cost: int + actual_gas_used: int + success: bool + reason: str + logs: List[LogReceipt] + + @classmethod + def from_bundler_response( + cls, + user_operation_receipt_response: Dict[str, Any], + ) -> "UserOperationReceipt": + return cls( + HexBytes(user_operation_receipt_response["userOpHash"]), + user_operation_receipt_response["entryPoint"], + user_operation_receipt_response["sender"], + int(user_operation_receipt_response["nonce"], 16), + user_operation_receipt_response["paymaster"], + int(user_operation_receipt_response["actualGasCost"], 16), + int(user_operation_receipt_response["actualGasUsed"], 16), + user_operation_receipt_response["success"], + user_operation_receipt_response["reason"], + user_operation_receipt_response["logs"], + ) + + def get_deposit(self) -> int: + """ + :return: Deposited value on the entrypoint for running the UserOperationReceipt + """ + deposited = 0 + for log in self.logs: + if ( + len(log["topics"]) == 2 + and HexBytes(log["topics"][0]) == DEPOSIT_EVENT_TOPIC + and Web3.to_checksum_address(log["address"]) == self.entry_point + and Web3.to_checksum_address(log["topics"][1][-40:]) == self.sender + ): + deposited += int(log["data"], 16) + return deposited + + def get_module_address(self) -> Optional[ChecksumAddress]: + """ + Use Safe's `ExecutionFromModuleSuccess` event to get the 4337 module address + + :return: If using a ``Safe``, the ``4337 module address`` used, ``None`` otherwise + """ + for log in reversed(self.logs): + if ( + len(log["topics"]) == 2 + and HexBytes(log["topics"][0]) == EXECUTION_FROM_MODULE_SUCCESS_TOPIC + and Web3.to_checksum_address(log["address"]) == self.sender + ): + return Web3.to_checksum_address(log["topics"][1][-40:]) + return None diff --git a/gnosis/eth/tests/account_abstraction/test_bundler_client.py b/gnosis/eth/tests/account_abstraction/test_bundler_client.py index ebf0b0c29..7bcfbe3aa 100644 --- a/gnosis/eth/tests/account_abstraction/test_bundler_client.py +++ b/gnosis/eth/tests/account_abstraction/test_bundler_client.py @@ -11,13 +11,13 @@ BundlerClientConnectionException, BundlerClientResponseException, UserOperation, + UserOperationReceipt, ) from ..mocks.mock_bundler import ( safe_4337_user_operation_hash_mock, supported_entrypoint_mock, user_operation_mock, user_operation_receipt_mock, - user_operation_receipt_parsed_mock, ) @@ -77,9 +77,13 @@ def test_get_user_operation_receipt(self, mock_session: MagicMock): return_value=copy.deepcopy(user_operation_receipt_mock) ) self.bundler.get_user_operation_receipt.cache_clear() + + expected_user_operation_receipt = UserOperationReceipt.from_bundler_response( + user_operation_receipt_mock["result"] + ) self.assertEqual( self.bundler.get_user_operation_receipt(user_operation_hash), - user_operation_receipt_parsed_mock["result"], + expected_user_operation_receipt, ) mock_session.return_value.json = MagicMock( return_value={ @@ -125,6 +129,9 @@ def test_get_user_operation_and_receipt(self, mock_session: MagicMock): expected_user_operation = UserOperation.from_bundler_response( user_operation_hash, user_operation_mock["result"] ) + expected_user_operation_receipt = UserOperationReceipt.from_bundler_response( + user_operation_receipt_mock["result"] + ) ( user_operation, user_operation_receipt, @@ -134,10 +141,7 @@ def test_get_user_operation_and_receipt(self, mock_session: MagicMock): user_operation, expected_user_operation, ) - self.assertDictEqual( - user_operation_receipt, - user_operation_receipt_parsed_mock["result"], - ) + self.assertEqual(user_operation_receipt, expected_user_operation_receipt) mock_session.return_value.json = MagicMock( return_value={ "jsonrpc": "2.0", diff --git a/gnosis/eth/tests/account_abstraction/test_e2e_bundler_client.py b/gnosis/eth/tests/account_abstraction/test_e2e_bundler_client.py index 027e8c746..ad91ccc1d 100644 --- a/gnosis/eth/tests/account_abstraction/test_e2e_bundler_client.py +++ b/gnosis/eth/tests/account_abstraction/test_e2e_bundler_client.py @@ -4,13 +4,12 @@ import pytest -from ...account_abstraction import BundlerClient, UserOperation +from ...account_abstraction import BundlerClient, UserOperation, UserOperationReceipt from ..mocks.mock_bundler import ( safe_4337_user_operation_hash_mock, supported_entrypoint_mock, user_operation_mock, user_operation_receipt_mock, - user_operation_receipt_parsed_mock, ) @@ -36,10 +35,13 @@ def test_get_user_operation_by_hash(self): def test_get_user_operation_receipt(self): user_operation_hash = safe_4337_user_operation_hash_mock.hex() + expected_user_operation_receipt = UserOperationReceipt.from_bundler_response( + user_operation_receipt_mock["result"] + ) self.assertEqual( self.bundler.get_user_operation_receipt(user_operation_hash), - user_operation_receipt_mock["result"], + expected_user_operation_receipt, ) @pytest.mark.xfail(reason="Some bundlers don't support batch requests") @@ -49,6 +51,9 @@ def test_get_user_operation_and_receipt(self): expected_user_operation = UserOperation.from_bundler_response( user_operation_hash, user_operation_mock["result"] ) + expected_user_operation_receipt = UserOperationReceipt.from_bundler_response( + user_operation_receipt_mock["result"] + ) ( user_operation, user_operation_receipt, @@ -57,9 +62,9 @@ def test_get_user_operation_and_receipt(self): user_operation, expected_user_operation, ) - self.assertDictEqual( + self.assertEqual( user_operation_receipt, - user_operation_receipt_parsed_mock["result"], + expected_user_operation_receipt, ) def test_supported_entry_points(self): diff --git a/gnosis/eth/tests/account_abstraction/test_user_operation.py b/gnosis/eth/tests/account_abstraction/test_user_operation.py index 5d171c702..d370213a7 100644 --- a/gnosis/eth/tests/account_abstraction/test_user_operation.py +++ b/gnosis/eth/tests/account_abstraction/test_user_operation.py @@ -1,7 +1,7 @@ from unittest import TestCase -from gnosis.eth.account_abstraction import UserOperation -from gnosis.eth.tests.mocks.mock_bundler import ( +from ...account_abstraction import UserOperation +from ..mocks.mock_bundler import ( safe_4337_chain_id_mock, safe_4337_user_operation_hash_mock, user_operation_mock, diff --git a/gnosis/eth/tests/account_abstraction/test_user_operation_receipt.py b/gnosis/eth/tests/account_abstraction/test_user_operation_receipt.py new file mode 100644 index 000000000..06bef2c7d --- /dev/null +++ b/gnosis/eth/tests/account_abstraction/test_user_operation_receipt.py @@ -0,0 +1,22 @@ +from unittest import TestCase + +from ...account_abstraction import UserOperationReceipt +from ..mocks.mock_bundler import user_operation_receipt_mock + + +class TestUserOperation(TestCase): + def setUp(self): + super().setUp() + self.user_operation_receipt = UserOperationReceipt.from_bundler_response( + user_operation_receipt_mock["result"] + ) + + def test_calculate_deposit(self): + expected_value = 759_940_285_250_436 + self.assertEqual(self.user_operation_receipt.get_deposit(), expected_value) + + def test_get_module_address(self): + expected_value = "0xa581c4A4DB7175302464fF3C06380BC3270b4037" + self.assertEqual( + self.user_operation_receipt.get_module_address(), expected_value + ) diff --git a/gnosis/eth/tests/mocks/mock_bundler.py b/gnosis/eth/tests/mocks/mock_bundler.py index 7bd9f4472..2e6cc9283 100644 --- a/gnosis/eth/tests/mocks/mock_bundler.py +++ b/gnosis/eth/tests/mocks/mock_bundler.py @@ -385,350 +385,6 @@ }, } -# HexStr parsed into integers -user_operation_receipt_parsed_mock = { - "jsonrpc": "2.0", - "id": 1, - "result": { - "userOpHash": "0x39b3e2171c04539d9b3f848d04364dfaa42cc0b412ff65ce2a85c566cf8bf281", - "entryPoint": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789", - "sender": "0xB0B5c0578Aa134b0496a6C0e51A7aae47C522861", - "nonce": 0, - "paymaster": "0x0000000000000000000000000000000000000000", - "actualGasCost": 501326604934692, - "actualGasUsed": 426098, - "success": True, - "reason": "", - "logs": [ - { - "address": "0xb0b5c0578aa134b0496a6c0e51a7aae47c522861", - "topics": [ - "0xecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f8440", - "0x000000000000000000000000a581c4a4db7175302464ff3c06380bc3270b4037", - ], - "data": "0x", - "blockHash": "0xcc466b284f4030ee3f5941a2c8e36892262bf583611c902fe5558a595af47e13", - "blockNumber": "0x50b0da", - "transactionHash": "0xf8dab30ed3c8814ee9a67770ee68f8fb83e6247706c24371a76e7cd8d348b0e3", - "transactionIndex": "0x85", - "logIndex": "0xc2", - "removed": False, - }, - { - "address": "0xb0b5c0578aa134b0496a6c0e51a7aae47c522861", - "topics": [ - "0x141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a8", - "0x0000000000000000000000004e1dcf7ad4e460cfd30791ccc4f9c8a4f820ec67", - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000008ecd4ec46d4d2a6b64fe960b3d64e8b94b2234eb000000000000000000000000a581c4a4db7175302464ff3c06380bc3270b403700000000000000000000000000000000000000000000000000000000000000010000000000000000000000005ac255889882acd3da2aa939679e3f3d4cea221e", - "blockHash": "0xcc466b284f4030ee3f5941a2c8e36892262bf583611c902fe5558a595af47e13", - "blockNumber": "0x50b0da", - "transactionHash": "0xf8dab30ed3c8814ee9a67770ee68f8fb83e6247706c24371a76e7cd8d348b0e3", - "transactionIndex": "0x85", - "logIndex": "0xc3", - "removed": False, - }, - { - "address": "0x4e1dcf7ad4e460cfd30791ccc4f9c8a4f820ec67", - "topics": [ - "0x4f51faf6c4561ff95f067657e43439f0f856d97c04d9ec9070a6199ad418e235", - "0x000000000000000000000000b0b5c0578aa134b0496a6c0e51a7aae47c522861", - ], - "data": "0x00000000000000000000000029fcb43b46531bca003ddc8fcb67ffe91900c762", - "blockHash": "0xcc466b284f4030ee3f5941a2c8e36892262bf583611c902fe5558a595af47e13", - "blockNumber": "0x50b0da", - "transactionHash": "0xf8dab30ed3c8814ee9a67770ee68f8fb83e6247706c24371a76e7cd8d348b0e3", - "transactionIndex": "0x85", - "logIndex": "0xc4", - "removed": False, - }, - { - "address": "0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789", - "topics": [ - "0xd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d", - "0x39b3e2171c04539d9b3f848d04364dfaa42cc0b412ff65ce2a85c566cf8bf281", - "0x000000000000000000000000b0b5c0578aa134b0496a6c0e51a7aae47c522861", - ], - "data": "0x0000000000000000000000004e1dcf7ad4e460cfd30791ccc4f9c8a4f820ec670000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xcc466b284f4030ee3f5941a2c8e36892262bf583611c902fe5558a595af47e13", - "blockNumber": "0x50b0da", - "transactionHash": "0xf8dab30ed3c8814ee9a67770ee68f8fb83e6247706c24371a76e7cd8d348b0e3", - "transactionIndex": "0x85", - "logIndex": "0xc5", - "removed": False, - }, - { - "address": "0xb0b5c0578aa134b0496a6c0e51a7aae47c522861", - "topics": [ - "0xb648d3644f584ed1c2232d53c46d87e693586486ad0d1175f8656013110b714e" - ], - "data": "0x000000000000000000000000a581c4a4db7175302464ff3c06380bc3270b40370000000000000000000000005ff137d4b0fdcd49dca30c7cf57e578a026d27890000000000000000000000000000000000000000000000000002b32962c0bb8400000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xcc466b284f4030ee3f5941a2c8e36892262bf583611c902fe5558a595af47e13", - "blockNumber": "0x50b0da", - "transactionHash": "0xf8dab30ed3c8814ee9a67770ee68f8fb83e6247706c24371a76e7cd8d348b0e3", - "transactionIndex": "0x85", - "logIndex": "0xc6", - "removed": False, - }, - { - "address": "0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789", - "topics": [ - "0x2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c4", - "0x000000000000000000000000b0b5c0578aa134b0496a6c0e51a7aae47c522861", - ], - "data": "0x0000000000000000000000000000000000000000000000000002b32962c0bb84", - "blockHash": "0xcc466b284f4030ee3f5941a2c8e36892262bf583611c902fe5558a595af47e13", - "blockNumber": "0x50b0da", - "transactionHash": "0xf8dab30ed3c8814ee9a67770ee68f8fb83e6247706c24371a76e7cd8d348b0e3", - "transactionIndex": "0x85", - "logIndex": "0xc7", - "removed": False, - }, - { - "address": "0xb0b5c0578aa134b0496a6c0e51a7aae47c522861", - "topics": [ - "0x6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb8", - "0x000000000000000000000000a581c4a4db7175302464ff3c06380bc3270b4037", - ], - "data": "0x", - "blockHash": "0xcc466b284f4030ee3f5941a2c8e36892262bf583611c902fe5558a595af47e13", - "blockNumber": "0x50b0da", - "transactionHash": "0xf8dab30ed3c8814ee9a67770ee68f8fb83e6247706c24371a76e7cd8d348b0e3", - "transactionIndex": "0x85", - "logIndex": "0xc8", - "removed": False, - }, - { - "address": "0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789", - "topics": [ - "0xbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972" - ], - "data": "0x", - "blockHash": "0xcc466b284f4030ee3f5941a2c8e36892262bf583611c902fe5558a595af47e13", - "blockNumber": "0x50b0da", - "transactionHash": "0xf8dab30ed3c8814ee9a67770ee68f8fb83e6247706c24371a76e7cd8d348b0e3", - "transactionIndex": "0x85", - "logIndex": "0xc9", - "removed": False, - }, - { - "address": "0xb0b5c0578aa134b0496a6c0e51a7aae47c522861", - "topics": [ - "0xb648d3644f584ed1c2232d53c46d87e693586486ad0d1175f8656013110b714e" - ], - "data": "0x000000000000000000000000a581c4a4db7175302464ff3c06380bc3270b403700000000000000000000000002270bd144e70ce6963ba02f575776a16184e1e600000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xcc466b284f4030ee3f5941a2c8e36892262bf583611c902fe5558a595af47e13", - "blockNumber": "0x50b0da", - "transactionHash": "0xf8dab30ed3c8814ee9a67770ee68f8fb83e6247706c24371a76e7cd8d348b0e3", - "transactionIndex": "0x85", - "logIndex": "0xca", - "removed": False, - }, - { - "address": "0xb0b5c0578aa134b0496a6c0e51a7aae47c522861", - "topics": [ - "0x6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb8", - "0x000000000000000000000000a581c4a4db7175302464ff3c06380bc3270b4037", - ], - "data": "0x", - "blockHash": "0xcc466b284f4030ee3f5941a2c8e36892262bf583611c902fe5558a595af47e13", - "blockNumber": "0x50b0da", - "transactionHash": "0xf8dab30ed3c8814ee9a67770ee68f8fb83e6247706c24371a76e7cd8d348b0e3", - "transactionIndex": "0x85", - "logIndex": "0xcb", - "removed": False, - }, - { - "address": "0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789", - "topics": [ - "0x49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f", - "0x39b3e2171c04539d9b3f848d04364dfaa42cc0b412ff65ce2a85c566cf8bf281", - "0x000000000000000000000000b0b5c0578aa134b0496a6c0e51a7aae47c522861", - "0x0000000000000000000000000000000000000000000000000000000000000000", - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000001c7f432341e240000000000000000000000000000000000000000000000000000000000068072", - "blockHash": "0xcc466b284f4030ee3f5941a2c8e36892262bf583611c902fe5558a595af47e13", - "blockNumber": "0x50b0da", - "transactionHash": "0xf8dab30ed3c8814ee9a67770ee68f8fb83e6247706c24371a76e7cd8d348b0e3", - "transactionIndex": "0x85", - "logIndex": "0xcc", - "removed": False, - }, - ], - "receipt": { - "transactionHash": "0xf8dab30ed3c8814ee9a67770ee68f8fb83e6247706c24371a76e7cd8d348b0e3", - "transactionIndex": "0x85", - "blockHash": "0xcc466b284f4030ee3f5941a2c8e36892262bf583611c902fe5558a595af47e13", - "blockNumber": "0x50b0da", - "from": "0xd53eb5203e367bbdd4f72338938224881fc501ab", - "to": "0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789", - "cumulativeGasUsed": "0xd2a354", - "gasUsed": "0x67c20", - "contractAddress": None, - "logs": [ - { - "address": "0xb0b5c0578aa134b0496a6c0e51a7aae47c522861", - "topics": [ - "0xecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f8440", - "0x000000000000000000000000a581c4a4db7175302464ff3c06380bc3270b4037", - ], - "data": "0x", - "blockHash": "0xcc466b284f4030ee3f5941a2c8e36892262bf583611c902fe5558a595af47e13", - "blockNumber": "0x50b0da", - "transactionHash": "0xf8dab30ed3c8814ee9a67770ee68f8fb83e6247706c24371a76e7cd8d348b0e3", - "transactionIndex": "0x85", - "logIndex": "0xc2", - "removed": False, - }, - { - "address": "0xb0b5c0578aa134b0496a6c0e51a7aae47c522861", - "topics": [ - "0x141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a8", - "0x0000000000000000000000004e1dcf7ad4e460cfd30791ccc4f9c8a4f820ec67", - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000008ecd4ec46d4d2a6b64fe960b3d64e8b94b2234eb000000000000000000000000a581c4a4db7175302464ff3c06380bc3270b403700000000000000000000000000000000000000000000000000000000000000010000000000000000000000005ac255889882acd3da2aa939679e3f3d4cea221e", - "blockHash": "0xcc466b284f4030ee3f5941a2c8e36892262bf583611c902fe5558a595af47e13", - "blockNumber": "0x50b0da", - "transactionHash": "0xf8dab30ed3c8814ee9a67770ee68f8fb83e6247706c24371a76e7cd8d348b0e3", - "transactionIndex": "0x85", - "logIndex": "0xc3", - "removed": False, - }, - { - "address": "0x4e1dcf7ad4e460cfd30791ccc4f9c8a4f820ec67", - "topics": [ - "0x4f51faf6c4561ff95f067657e43439f0f856d97c04d9ec9070a6199ad418e235", - "0x000000000000000000000000b0b5c0578aa134b0496a6c0e51a7aae47c522861", - ], - "data": "0x00000000000000000000000029fcb43b46531bca003ddc8fcb67ffe91900c762", - "blockHash": "0xcc466b284f4030ee3f5941a2c8e36892262bf583611c902fe5558a595af47e13", - "blockNumber": "0x50b0da", - "transactionHash": "0xf8dab30ed3c8814ee9a67770ee68f8fb83e6247706c24371a76e7cd8d348b0e3", - "transactionIndex": "0x85", - "logIndex": "0xc4", - "removed": False, - }, - { - "address": "0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789", - "topics": [ - "0xd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d", - "0x39b3e2171c04539d9b3f848d04364dfaa42cc0b412ff65ce2a85c566cf8bf281", - "0x000000000000000000000000b0b5c0578aa134b0496a6c0e51a7aae47c522861", - ], - "data": "0x0000000000000000000000004e1dcf7ad4e460cfd30791ccc4f9c8a4f820ec670000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xcc466b284f4030ee3f5941a2c8e36892262bf583611c902fe5558a595af47e13", - "blockNumber": "0x50b0da", - "transactionHash": "0xf8dab30ed3c8814ee9a67770ee68f8fb83e6247706c24371a76e7cd8d348b0e3", - "transactionIndex": "0x85", - "logIndex": "0xc5", - "removed": False, - }, - { - "address": "0xb0b5c0578aa134b0496a6c0e51a7aae47c522861", - "topics": [ - "0xb648d3644f584ed1c2232d53c46d87e693586486ad0d1175f8656013110b714e" - ], - "data": "0x000000000000000000000000a581c4a4db7175302464ff3c06380bc3270b40370000000000000000000000005ff137d4b0fdcd49dca30c7cf57e578a026d27890000000000000000000000000000000000000000000000000002b32962c0bb8400000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xcc466b284f4030ee3f5941a2c8e36892262bf583611c902fe5558a595af47e13", - "blockNumber": "0x50b0da", - "transactionHash": "0xf8dab30ed3c8814ee9a67770ee68f8fb83e6247706c24371a76e7cd8d348b0e3", - "transactionIndex": "0x85", - "logIndex": "0xc6", - "removed": False, - }, - { - "address": "0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789", - "topics": [ - "0x2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c4", - "0x000000000000000000000000b0b5c0578aa134b0496a6c0e51a7aae47c522861", - ], - "data": "0x0000000000000000000000000000000000000000000000000002b32962c0bb84", - "blockHash": "0xcc466b284f4030ee3f5941a2c8e36892262bf583611c902fe5558a595af47e13", - "blockNumber": "0x50b0da", - "transactionHash": "0xf8dab30ed3c8814ee9a67770ee68f8fb83e6247706c24371a76e7cd8d348b0e3", - "transactionIndex": "0x85", - "logIndex": "0xc7", - "removed": False, - }, - { - "address": "0xb0b5c0578aa134b0496a6c0e51a7aae47c522861", - "topics": [ - "0x6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb8", - "0x000000000000000000000000a581c4a4db7175302464ff3c06380bc3270b4037", - ], - "data": "0x", - "blockHash": "0xcc466b284f4030ee3f5941a2c8e36892262bf583611c902fe5558a595af47e13", - "blockNumber": "0x50b0da", - "transactionHash": "0xf8dab30ed3c8814ee9a67770ee68f8fb83e6247706c24371a76e7cd8d348b0e3", - "transactionIndex": "0x85", - "logIndex": "0xc8", - "removed": False, - }, - { - "address": "0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789", - "topics": [ - "0xbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972" - ], - "data": "0x", - "blockHash": "0xcc466b284f4030ee3f5941a2c8e36892262bf583611c902fe5558a595af47e13", - "blockNumber": "0x50b0da", - "transactionHash": "0xf8dab30ed3c8814ee9a67770ee68f8fb83e6247706c24371a76e7cd8d348b0e3", - "transactionIndex": "0x85", - "logIndex": "0xc9", - "removed": False, - }, - { - "address": "0xb0b5c0578aa134b0496a6c0e51a7aae47c522861", - "topics": [ - "0xb648d3644f584ed1c2232d53c46d87e693586486ad0d1175f8656013110b714e" - ], - "data": "0x000000000000000000000000a581c4a4db7175302464ff3c06380bc3270b403700000000000000000000000002270bd144e70ce6963ba02f575776a16184e1e600000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xcc466b284f4030ee3f5941a2c8e36892262bf583611c902fe5558a595af47e13", - "blockNumber": "0x50b0da", - "transactionHash": "0xf8dab30ed3c8814ee9a67770ee68f8fb83e6247706c24371a76e7cd8d348b0e3", - "transactionIndex": "0x85", - "logIndex": "0xca", - "removed": False, - }, - { - "address": "0xb0b5c0578aa134b0496a6c0e51a7aae47c522861", - "topics": [ - "0x6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb8", - "0x000000000000000000000000a581c4a4db7175302464ff3c06380bc3270b4037", - ], - "data": "0x", - "blockHash": "0xcc466b284f4030ee3f5941a2c8e36892262bf583611c902fe5558a595af47e13", - "blockNumber": "0x50b0da", - "transactionHash": "0xf8dab30ed3c8814ee9a67770ee68f8fb83e6247706c24371a76e7cd8d348b0e3", - "transactionIndex": "0x85", - "logIndex": "0xcb", - "removed": False, - }, - { - "address": "0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789", - "topics": [ - "0x49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f", - "0x39b3e2171c04539d9b3f848d04364dfaa42cc0b412ff65ce2a85c566cf8bf281", - "0x000000000000000000000000b0b5c0578aa134b0496a6c0e51a7aae47c522861", - "0x0000000000000000000000000000000000000000000000000000000000000000", - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000001c7f432341e240000000000000000000000000000000000000000000000000000000000068072", - "blockHash": "0xcc466b284f4030ee3f5941a2c8e36892262bf583611c902fe5558a595af47e13", - "blockNumber": "0x50b0da", - "transactionHash": "0xf8dab30ed3c8814ee9a67770ee68f8fb83e6247706c24371a76e7cd8d348b0e3", - "transactionIndex": "0x85", - "logIndex": "0xcc", - "removed": False, - }, - ], - "status": "0x1", - "logsBloom": "0x080004000000900000000000000000008000000000000000000000000200000000080000000000000002200100000000001000000000000080000200000000000000100000000000000000000000000000000000000004080040000000002000000000000a00000005000000000008000000000001000000000000000002000008000120204002000000000000400000000002000004000000000000000000000000000000000010005000000000000002000000000000000000020000000000000000000000000000010000000000000000000000200000000000000000200000400c0000010000000000000008100220000000000000080000000000000000", - "type": "0x2", - "effectiveGasPrice": "0xa85f9ad", - }, - }, -} - supported_entrypoint_mock = { "jsonrpc": "2.0", "id": 1,