Skip to content

Commit 7e57fe4

Browse files
committed
Add more RPC methods
1 parent dd909d5 commit 7e57fe4

2 files changed

Lines changed: 259 additions & 0 deletions

File tree

pons/_client_rpc.py

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,3 +377,103 @@ async def eth_uninstall_filter(
377377
return await rpc_call_at_pin(
378378
self._provider_session, filter_.provider_path, "eth_uninstallFilter", bool, filter_.id
379379
)
380+
381+
async def web3_client_version(self) -> str:
382+
"""Calls the ``web3_clientVersion`` RPC method."""
383+
return await rpc_call(self._provider_session, "web3_clientVersion", str)
384+
385+
async def web3_sha3(self, data: bytes) -> bytes:
386+
"""Calls the ``web3_sha3`` RPC method."""
387+
return await rpc_call(self._provider_session, "web3_sha3", bytes, data)
388+
389+
async def net_listening(self) -> bool:
390+
"""Calls the ``net_listening`` RPC method."""
391+
return await rpc_call(self._provider_session, "net_listening", bool)
392+
393+
async def net_peer_count(self) -> int:
394+
"""Calls the ``net_peerCount`` RPC method."""
395+
return await rpc_call(self._provider_session, "net_peerCount", int)
396+
397+
async def eth_coinbase(self) -> Address:
398+
"""Calls the ``eth_coinbase`` RPC method."""
399+
return await rpc_call(self._provider_session, "eth_coinbase", Address)
400+
401+
async def eth_accounts(self) -> list[Address]:
402+
"""Calls the ``eth_accounts`` RPC method."""
403+
return await rpc_call(self._provider_session, "eth_accounts", list[Address])
404+
405+
async def eth_get_block_transaction_count_by_hash(self, block_hash: BlockHash) -> int:
406+
"""Calls the ``eth_getBlockTransactionCountByHash`` RPC method."""
407+
return await rpc_call(
408+
self._provider_session, "eth_getBlockTransactionCountByHash", int, block_hash
409+
)
410+
411+
async def eth_get_block_transaction_count_by_number(self, block: Block) -> int:
412+
"""Calls the ``eth_getBlockTransactionCountByNumber`` RPC method."""
413+
return await rpc_call(
414+
self._provider_session, "eth_getBlockTransactionCountByNumber", int, block
415+
)
416+
417+
async def eth_get_uncles_count_by_block_hash(self, block_hash: BlockHash) -> int:
418+
"""Calls the ``eth_getUncleCountByBlockHash`` RPC method."""
419+
return await rpc_call(
420+
self._provider_session, "eth_getUncleCountByBlockHash", int, block_hash
421+
)
422+
423+
async def eth_get_uncles_count_by_block_number(self, block: Block) -> int:
424+
"""Calls the ``eth_getUncleCountByBlockNumber`` RPC method."""
425+
return await rpc_call(self._provider_session, "eth_getUncleCountByBlockNumber", int, block)
426+
427+
async def eth_get_transaction_by_block_hash_and_index(
428+
self, block_hash: BlockHash, index: int
429+
) -> TxInfo:
430+
"""Calls the ``eth_getTransactionByBlockHashAndIndex`` RPC method."""
431+
return await rpc_call(
432+
self._provider_session,
433+
"eth_getTransactionByBlockHashAndIndex",
434+
TxInfo,
435+
block_hash,
436+
index,
437+
)
438+
439+
async def eth_get_transaction_by_block_number_and_index(
440+
self, block: Block, index: int
441+
) -> TxInfo:
442+
"""Calls the ``eth_getTransactionByBlockNumberAndIndex`` RPC method."""
443+
return await rpc_call(
444+
self._provider_session, "eth_getTransactionByBlockNumberAndIndex", TxInfo, block, index
445+
)
446+
447+
async def eth_get_uncle_by_block_hash_and_index(
448+
self, block_hash: BlockHash, index: int
449+
) -> None | BlockInfo:
450+
"""Calls the ``eth_getUncleByBlockHashAndIndex`` RPC method."""
451+
# Need an explicit cast, mypy doesn't work with union types correctly.
452+
# See https://github.com/python/mypy/issues/16935
453+
return cast(
454+
"None | BlockInfo",
455+
await rpc_call(
456+
self._provider_session,
457+
"eth_getUncleByBlockHashAndIndex",
458+
None | BlockInfo, # type: ignore[arg-type]
459+
block_hash,
460+
index,
461+
),
462+
)
463+
464+
async def eth_get_uncle_by_block_number_and_index(
465+
self, block: Block, index: int
466+
) -> None | BlockInfo:
467+
"""Calls the ``eth_getUncleByBlockNumberAndIndex`` RPC method."""
468+
# Need an explicit cast, mypy doesn't work with union types correctly.
469+
# See https://github.com/python/mypy/issues/16935
470+
return cast(
471+
"None | BlockInfo",
472+
await rpc_call(
473+
self._provider_session,
474+
"eth_getUncleByBlockNumberAndIndex",
475+
None | BlockInfo, # type: ignore[arg-type]
476+
block,
477+
index,
478+
),
479+
)

tests/test_client_rpc.py

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,3 +750,162 @@ async def test_eth_uninstall_filter(session: ClientSession) -> None:
750750
assert await session.rpc.eth_uninstall_filter(block_filter)
751751
# no such filter anymore
752752
assert not await session.rpc.eth_uninstall_filter(block_filter)
753+
754+
755+
async def test_web3_client_version(session: ClientSession) -> None:
756+
assert await session.rpc.web3_client_version() == "Alysis testerchain"
757+
758+
759+
async def test_web3_sha3(session: ClientSession) -> None:
760+
data = b"12345678"
761+
assert await session.rpc.web3_sha3(data) == keccak(data)
762+
763+
764+
async def test_net_listening(session: ClientSession) -> None:
765+
assert await session.rpc.net_listening()
766+
767+
768+
async def test_net_peer_coont(session: ClientSession) -> None:
769+
assert await session.rpc.net_peer_count() == 42
770+
771+
772+
async def test_eth_coinbase(session: ClientSession) -> None:
773+
# That's what the testerchain is expected to return
774+
assert await session.rpc.eth_coinbase() == Address(b"\x00" * 20)
775+
776+
777+
async def test_eth_accounts(session: ClientSession) -> None:
778+
# For now the testerchain does not support creating accounts
779+
assert await session.rpc.eth_accounts() == []
780+
781+
782+
async def test_eth_get_block_transaction_count_by_hash(
783+
local_provider: LocalProvider,
784+
session: ClientSession,
785+
root_signer: AccountSigner,
786+
another_signer: AccountSigner,
787+
) -> None:
788+
local_provider.disable_auto_mine_transactions()
789+
await session.broadcast_transfer(root_signer, another_signer.address, Amount.ether(1))
790+
await session.broadcast_transfer(root_signer, another_signer.address, Amount.ether(2))
791+
local_provider.enable_auto_mine_transactions()
792+
block_info = await session.get_block(BlockLabel.LATEST)
793+
assert block_info is not None
794+
assert block_info.hash_ is not None
795+
796+
assert await session.rpc.eth_get_block_transaction_count_by_hash(block_info.hash_) == 2
797+
798+
799+
async def test_eth_get_block_transaction_count_by_number(
800+
local_provider: LocalProvider,
801+
session: ClientSession,
802+
root_signer: AccountSigner,
803+
another_signer: AccountSigner,
804+
) -> None:
805+
local_provider.disable_auto_mine_transactions()
806+
await session.broadcast_transfer(root_signer, another_signer.address, Amount.ether(1))
807+
await session.broadcast_transfer(root_signer, another_signer.address, Amount.ether(2))
808+
local_provider.enable_auto_mine_transactions()
809+
810+
assert await session.rpc.eth_get_block_transaction_count_by_number(BlockLabel.LATEST) == 2
811+
812+
813+
async def test_eth_get_uncles_count_by_block_hash(
814+
session: ClientSession,
815+
root_signer: AccountSigner,
816+
another_signer: AccountSigner,
817+
) -> None:
818+
await session.transfer(root_signer, another_signer.address, Amount.ether(1))
819+
block_info = await session.get_block(BlockLabel.LATEST)
820+
assert block_info is not None
821+
assert block_info.hash_ is not None
822+
823+
assert await session.rpc.eth_get_uncles_count_by_block_hash(block_info.hash_) == 0
824+
825+
826+
async def test_eth_get_uncles_count_by_block_number(
827+
session: ClientSession,
828+
root_signer: AccountSigner,
829+
another_signer: AccountSigner,
830+
) -> None:
831+
await session.transfer(root_signer, another_signer.address, Amount.ether(1))
832+
assert await session.rpc.eth_get_uncles_count_by_block_number(BlockLabel.LATEST) == 0
833+
834+
835+
async def test_eth_get_transaction_by_block_hash_and_index(
836+
local_provider: LocalProvider,
837+
session: ClientSession,
838+
root_signer: AccountSigner,
839+
another_signer: AccountSigner,
840+
) -> None:
841+
local_provider.disable_auto_mine_transactions()
842+
await session.broadcast_transfer(root_signer, another_signer.address, Amount.ether(1))
843+
await session.broadcast_transfer(root_signer, another_signer.address, Amount.ether(2))
844+
local_provider.enable_auto_mine_transactions()
845+
block_info = await session.get_block(BlockLabel.LATEST, with_transactions=True)
846+
assert block_info is not None
847+
assert block_info.hash_ is not None
848+
849+
assert (
850+
await session.rpc.eth_get_transaction_by_block_hash_and_index(block_info.hash_, 0)
851+
== block_info.transactions[0]
852+
)
853+
assert (
854+
await session.rpc.eth_get_transaction_by_block_hash_and_index(block_info.hash_, 1)
855+
== block_info.transactions[1]
856+
)
857+
858+
message = (
859+
"Provider error: RPC error (RPCErrorCode.METHOD_NOT_FOUND): "
860+
"2 transactions available, requested index 2"
861+
)
862+
with pytest.raises(ProviderError, match=re.escape(message)):
863+
assert await session.rpc.eth_get_transaction_by_block_hash_and_index(block_info.hash_, 2)
864+
865+
866+
async def test_eth_get_transaction_by_block_number_and_index(
867+
local_provider: LocalProvider,
868+
session: ClientSession,
869+
root_signer: AccountSigner,
870+
another_signer: AccountSigner,
871+
) -> None:
872+
local_provider.disable_auto_mine_transactions()
873+
await session.broadcast_transfer(root_signer, another_signer.address, Amount.ether(1))
874+
await session.broadcast_transfer(root_signer, another_signer.address, Amount.ether(2))
875+
local_provider.enable_auto_mine_transactions()
876+
block_info = await session.get_block(BlockLabel.LATEST, with_transactions=True)
877+
assert block_info is not None
878+
879+
assert (
880+
await session.rpc.eth_get_transaction_by_block_number_and_index(BlockLabel.LATEST, 0)
881+
== block_info.transactions[0]
882+
)
883+
assert (
884+
await session.rpc.eth_get_transaction_by_block_number_and_index(BlockLabel.LATEST, 1)
885+
== block_info.transactions[1]
886+
)
887+
888+
889+
async def test_eth_get_uncle_by_block_hash_and_index(
890+
session: ClientSession,
891+
root_signer: AccountSigner,
892+
another_signer: AccountSigner,
893+
) -> None:
894+
await session.transfer(root_signer, another_signer.address, Amount.ether(1))
895+
block_info = await session.get_block(BlockLabel.LATEST, with_transactions=True)
896+
assert block_info is not None
897+
assert block_info.hash_ is not None
898+
899+
# How do we make the testerchain create uncles?
900+
assert await session.rpc.eth_get_uncle_by_block_hash_and_index(block_info.hash_, 0) is None
901+
902+
903+
async def test_eth_get_uncle_by_block_number_and_index(
904+
session: ClientSession,
905+
root_signer: AccountSigner,
906+
another_signer: AccountSigner,
907+
) -> None:
908+
await session.transfer(root_signer, another_signer.address, Amount.ether(1))
909+
910+
# How do we make the testerchain create uncles?
911+
assert await session.rpc.eth_get_uncle_by_block_number_and_index(BlockLabel.LATEST, 0) is None

0 commit comments

Comments
 (0)