Skip to content

Commit 4cbb780

Browse files
authored
feature: add RPC eth_getBlockReceipts (#3247)
* feat(eth): implement eth_getBlockReceipts * docs(news): 3247.feature --------- Signed-off-by: jsvisa <[email protected]>
1 parent 07a5748 commit 4cbb780

File tree

8 files changed

+114
-16
lines changed

8 files changed

+114
-16
lines changed

newsfragments/3247.feature.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add support for ``eth_getRawTransactionByHash`` RPC method

tests/integration/test_ethereum_tester.py

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,26 @@ class TestEthereumTesterEthModule(EthModuleTest):
316316
EthModuleTest.test_eth_call_with_override_code,
317317
TypeError,
318318
)
319+
test_eth_getBlockReceipts_hash = not_implemented(
320+
EthModuleTest.test_eth_getBlockReceipts_hash,
321+
MethodUnavailable,
322+
)
323+
test_eth_getBlockReceipts_not_found = not_implemented(
324+
EthModuleTest.test_eth_getBlockReceipts_not_found,
325+
MethodUnavailable,
326+
)
327+
test_eth_getBlockReceipts_with_integer = not_implemented(
328+
EthModuleTest.test_eth_getBlockReceipts_with_integer,
329+
MethodUnavailable,
330+
)
331+
test_eth_getBlockReceipts_safe = not_implemented(
332+
EthModuleTest.test_eth_getBlockReceipts_safe,
333+
MethodUnavailable,
334+
)
335+
test_eth_getBlockReceipts_finalized = not_implemented(
336+
EthModuleTest.test_eth_getBlockReceipts_finalized,
337+
MethodUnavailable,
338+
)
319339

320340
def test_eth_getBlockByHash_pending(self, w3: "Web3") -> None:
321341
block = w3.eth.get_block("pending")
@@ -632,27 +652,11 @@ def test_eth_send_transaction_no_gas(self, eth_tester, w3, unlocked_account):
632652
def test_eth_send_transaction_no_max_fee(self, eth_tester, w3, unlocked_account):
633653
super().test_eth_send_transaction_no_max_fee(w3, unlocked_account)
634654

635-
def test_eth_getBlockByNumber_safe(
636-
self, w3: "Web3", empty_block: BlockData
637-
) -> None:
638-
super().test_eth_getBlockByNumber_safe(w3, empty_block)
639-
640-
def test_eth_getBlockByNumber_finalized(
641-
self, w3: "Web3", empty_block: BlockData
642-
) -> None:
643-
super().test_eth_getBlockByNumber_finalized(w3, empty_block)
644-
645-
def test_eth_fee_history(self, w3: "Web3") -> None:
646-
super().test_eth_fee_history(w3)
647-
648655
def test_eth_fee_history_with_integer(
649656
self, w3: "Web3", empty_block: BlockData
650657
) -> None:
651658
super().test_eth_fee_history_with_integer(w3, empty_block)
652659

653-
def test_eth_fee_history_with_no_reward_percentiles(self, w3: "Web3") -> None:
654-
super().test_eth_fee_history_no_reward_percentiles(w3)
655-
656660
def test_eth_get_balance_with_block_identifier(self, w3: "Web3") -> None:
657661
w3.testing.mine()
658662
miner_address = w3.eth.get_block(1)["miner"]

web3/_utils/method_formatters.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,7 @@ def apply_list_to_array_formatter(formatter: Any) -> Callable[..., Any]:
516516
),
517517
RPC.eth_getBalance: apply_formatter_at_index(to_hex_if_integer, 1),
518518
RPC.eth_getBlockByNumber: apply_formatter_at_index(to_hex_if_integer, 0),
519+
RPC.eth_getBlockReceipts: apply_formatter_at_index(to_hex_if_integer, 0),
519520
RPC.eth_getBlockTransactionCountByNumber: apply_formatter_at_index(
520521
to_hex_if_integer,
521522
0,
@@ -723,6 +724,7 @@ def subscription_formatter(value: Any) -> Union[HexBytes, HexStr, Dict[str, Any]
723724
RPC.eth_getBalance: to_integer_if_hex,
724725
RPC.eth_getBlockByHash: apply_formatter_if(is_not_null, block_formatter),
725726
RPC.eth_getBlockByNumber: apply_formatter_if(is_not_null, block_formatter),
727+
RPC.eth_getBlockReceipts: apply_formatter_to_array(receipt_formatter),
726728
RPC.eth_getBlockTransactionCountByHash: to_integer_if_hex,
727729
RPC.eth_getBlockTransactionCountByNumber: to_integer_if_hex,
728730
RPC.eth_getCode: HexBytes,
@@ -900,6 +902,7 @@ def raise_transaction_not_found_with_index(
900902
NULL_RESULT_FORMATTERS: Dict[RPCEndpoint, Callable[..., Any]] = {
901903
RPC.eth_getBlockByHash: raise_block_not_found,
902904
RPC.eth_getBlockByNumber: raise_block_not_found,
905+
RPC.eth_getBlockReceipts: raise_block_not_found,
903906
RPC.eth_getBlockTransactionCountByHash: raise_block_not_found,
904907
RPC.eth_getBlockTransactionCountByNumber: raise_block_not_found,
905908
RPC.eth_getUncleCountByBlockHash: raise_block_not_found,

web3/_utils/module_testing/eth_module.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -977,6 +977,39 @@ async def test_eth_getBlockByNumber_finalized(
977977
assert block is not None
978978
assert isinstance(block["number"], int)
979979

980+
@pytest.mark.asyncio
981+
async def test_eth_getBlockReceipts_hash(
982+
self, async_w3: "AsyncWeb3", async_empty_block: BlockData
983+
) -> None:
984+
receipts = await async_w3.eth.get_block_receipts(async_empty_block["hash"])
985+
assert isinstance(receipts, list)
986+
987+
@pytest.mark.asyncio
988+
async def test_eth_getBlockReceipts_not_found(self, async_w3: "AsyncWeb3") -> None:
989+
with pytest.raises(BlockNotFound):
990+
await async_w3.eth.get_block_receipts(UNKNOWN_HASH)
991+
992+
@pytest.mark.asyncio
993+
async def test_eth_getBlockReceipts_with_integer(
994+
self, async_w3: "AsyncWeb3", async_empty_block: BlockData
995+
) -> None:
996+
receipts = await async_w3.eth.get_block_receipts(async_empty_block["number"])
997+
assert isinstance(receipts, list)
998+
999+
@pytest.mark.asyncio
1000+
async def test_eth_getBlockReceipts_safe(
1001+
self, async_w3: "AsyncWeb3", async_empty_block: BlockData
1002+
) -> None:
1003+
receipts = await async_w3.eth.get_block_receipts("safe")
1004+
assert isinstance(receipts, list)
1005+
1006+
@pytest.mark.asyncio
1007+
async def test_eth_getBlockReceipts_finalized(
1008+
self, async_w3: "AsyncWeb3", async_empty_block: BlockData
1009+
) -> None:
1010+
receipts = await async_w3.eth.get_block_receipts("finalized")
1011+
assert isinstance(receipts, list)
1012+
9801013
@pytest.mark.asyncio
9811014
async def test_eth_get_block_by_number_full_transactions(
9821015
self, async_w3: "AsyncWeb3", async_block_with_txn: BlockData
@@ -4224,6 +4257,34 @@ def test_eth_getBlockByNumber_full_transactions(
42244257
transaction = block["transactions"][0]
42254258
assert transaction["hash"] == block_with_txn["transactions"][0] # type: ignore
42264259

4260+
def test_eth_getBlockReceipts_hash(
4261+
self, w3: "Web3", empty_block: BlockData
4262+
) -> None:
4263+
receipts = w3.eth.get_block_receipts(empty_block["hash"])
4264+
assert isinstance(receipts, list)
4265+
4266+
def test_eth_getBlockReceipts_not_found(self, w3: "Web3") -> None:
4267+
with pytest.raises(BlockNotFound):
4268+
w3.eth.get_block_receipts(UNKNOWN_HASH)
4269+
4270+
def test_eth_getBlockReceipts_with_integer(
4271+
self, w3: "Web3", empty_block: BlockData
4272+
) -> None:
4273+
receipts = w3.eth.get_block_receipts(empty_block["number"])
4274+
assert isinstance(receipts, list)
4275+
4276+
def test_eth_getBlockReceipts_safe(
4277+
self, w3: "Web3", empty_block: BlockData
4278+
) -> None:
4279+
receipts = w3.eth.get_block_receipts("safe")
4280+
assert isinstance(receipts, list)
4281+
4282+
def test_eth_getBlockReceipts_finalized(
4283+
self, w3: "Web3", empty_block: BlockData
4284+
) -> None:
4285+
receipts = w3.eth.get_block_receipts("finalized")
4286+
assert isinstance(receipts, list)
4287+
42274288
def test_eth_getTransactionByHash(self, w3: "Web3", mined_txn_hash: HexStr) -> None:
42284289
transaction = w3.eth.get_transaction(mined_txn_hash)
42294290
assert is_dict(transaction)

web3/_utils/rpc_abi.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class RPC:
5757
eth_getBalance = RPCEndpoint("eth_getBalance")
5858
eth_getBlockByHash = RPCEndpoint("eth_getBlockByHash")
5959
eth_getBlockByNumber = RPCEndpoint("eth_getBlockByNumber")
60+
eth_getBlockReceipts = RPCEndpoint("eth_getBlockReceipts")
6061
eth_getBlockTransactionCountByHash = RPCEndpoint(
6162
"eth_getBlockTransactionCountByHash"
6263
)

web3/eth/async_eth.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
BlockData,
7676
BlockIdentifier,
7777
BlockParams,
78+
BlockReceipts,
7879
CreateAccessListResponse,
7980
FeeHistory,
8081
FilterParams,
@@ -440,6 +441,20 @@ async def get_block(
440441
) -> BlockData:
441442
return await self._get_block(block_identifier, full_transactions)
442443

444+
# eth_getBlockReceipts
445+
446+
_get_block_receipts: Method[
447+
Callable[[BlockIdentifier], Awaitable[BlockReceipts]]
448+
] = Method(
449+
RPC.eth_getBlockReceipts,
450+
mungers=[default_root_munger],
451+
)
452+
453+
async def get_block_receipts(
454+
self, block_identifier: BlockIdentifier
455+
) -> BlockReceipts:
456+
return await self._get_block_receipts(block_identifier)
457+
443458
# eth_getBalance
444459

445460
_get_balance: Method[

web3/eth/eth.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
BlockData,
7373
BlockIdentifier,
7474
BlockParams,
75+
BlockReceipts,
7576
CreateAccessListResponse,
7677
FeeHistory,
7778
FilterParams,
@@ -411,6 +412,16 @@ def get_block(
411412
) -> BlockData:
412413
return self._get_block(block_identifier, full_transactions)
413414

415+
# eth_getBlockReceipts
416+
417+
_get_block_receipts: Method[Callable[[BlockIdentifier], BlockReceipts]] = Method(
418+
RPC.eth_getBlockReceipts,
419+
mungers=[default_root_munger],
420+
)
421+
422+
def get_block_receipts(self, block_identifier: BlockIdentifier) -> BlockReceipts:
423+
return self._get_block_receipts(block_identifier)
424+
414425
# eth_getBalance
415426

416427
_get_balance: Method[

web3/types.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,8 @@ class FeeHistory(TypedDict):
381381
},
382382
)
383383

384+
BlockReceipts = List[TxReceipt]
385+
384386

385387
class SignedTx(TypedDict, total=False):
386388
raw: bytes

0 commit comments

Comments
 (0)