Skip to content

Commit

Permalink
fix: issue with Block transactions when block.hash was None (#2426)
Browse files Browse the repository at this point in the history
Signed-off-by: fudancoder <[email protected].>
Co-authored-by: fudancoder <[email protected]>
  • Loading branch information
antazoey and fudancoder authored Dec 19, 2024
1 parent 443455b commit 835e1a0
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 2 deletions.
11 changes: 10 additions & 1 deletion src/ape/api/providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from subprocess import DEVNULL, PIPE, Popen
from typing import TYPE_CHECKING, Any, Optional, Union, cast

from eth_utils import to_hex
from pydantic import Field, computed_field, field_serializer, model_validator

from ape.api.networks import NetworkAPI
Expand Down Expand Up @@ -95,7 +96,11 @@ class BlockAPI(BaseInterfaceModel):

@log_instead_of_fail(default="<BlockAPI>")
def __repr__(self) -> str:
return super().__repr__()
repr_str = f"{self.__class__.__name__} number={self.number}"
if hash := self.hash:
repr_str = f"{repr_str} hash={to_hex(hash)}"

return f"<{repr_str}>"

@property
def datetime(self) -> datetime.datetime:
Expand Down Expand Up @@ -146,6 +151,10 @@ def transactions(self) -> list[TransactionAPI]:
"""
All transactions in a block.
"""
if self.hash is None:
# Unable to query transactions.
return []

try:
query = BlockTransactionQuery(columns=["*"], block_id=self.hash)
return cast(list[TransactionAPI], list(self.query_manager.query(query)))
Expand Down
23 changes: 23 additions & 0 deletions tests/functional/test_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@ def test_block(eth_tester_provider, vyper_contract_instance):
assert actual.number == data["number"]


def test_repr(block):
actual = repr(block)
expected = f"<Block number={block.number} hash={to_hex(block.hash)}>"
assert actual == expected

# Show it works when there is no hash.
block.hash = None
actual = repr(block)
expected = f"<Block number={block.number}>"
assert actual == expected


@pytest.mark.parametrize("mode", ("json", "python"))
def test_model_dump(block, mode):
actual = block.model_dump(mode=mode)
Expand Down Expand Up @@ -116,3 +128,14 @@ def test_model_validate_web3_block():
data = BlockData(number=123, timestamp=123, gasLimit=123, gasUsed=100) # type: ignore
actual = Block.model_validate(data)
assert actual.number == 123


def test_transactions(block):
actual = block.transactions
expected: list = []
assert actual == expected

# Ensure still works when hash is None (was a bug where this crashed).
block.hash = None
block.__dict__.pop("transactions", None) # Ensure not cached.
assert block.transactions == []
5 changes: 4 additions & 1 deletion tests/integration/cli/test_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,10 @@ def test_run_interactive(scripts_runner, integ_project):
scripts = [integ_project.scripts_folder / f"{s}.py" for s in error_names]

# Show that the variable namespace from the script is available in the console.
user_input = "local_variable\nape.chain.provider.mine()\nape.chain.blocks.head\nexit\n"
user_input = (
"local_variable\nape.chain.provider.mine()\n"
"print(f'timestamp={ape.chain.blocks.head.timestamp}')\nexit\n"
)

result = scripts_runner.invoke("--interactive", scripts[0].stem, input=user_input)
assert result.exit_code == 0, result.output
Expand Down

0 comments on commit 835e1a0

Please sign in to comment.