Skip to content
This repository was archived by the owner on Sep 8, 2025. It is now read-only.

Commit 1bb4097

Browse files
committed
Raise BlockNotFound if txns or uncles are missing
Also added tests. Was previously raising KeyError for missing transactions (although this has become a MissingTrieNode with the latest py-trie). Was previously raising HeaderNotFound for missing uncles.
1 parent ad33442 commit 1bb4097

File tree

5 files changed

+44
-5
lines changed

5 files changed

+44
-5
lines changed

eth/abc.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3197,13 +3197,18 @@ def get_block(self) -> BlockAPI:
31973197
def get_block_by_hash(self, block_hash: Hash32) -> BlockAPI:
31983198
"""
31993199
Return the requested block as specified by ``block_hash``.
3200+
3201+
:raise eth.exceptions.HeaderNotFound: if the header is missing
3202+
:raise eth.exceptions.BlockNotFound: if any part of the block body is missing
32003203
"""
32013204
...
32023205

32033206
@abstractmethod
32043207
def get_block_by_header(self, block_header: BlockHeaderAPI) -> BlockAPI:
32053208
"""
32063209
Return the requested block as specified by the ``block_header``.
3210+
3211+
:raise eth.exceptions.BlockNotFound: if any part of the block body is missing
32073212
"""
32083213
...
32093214

eth/db/chain.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,10 @@ def get_block_uncles(self, uncles_hash: Hash32) -> Tuple[BlockHeaderAPI, ...]:
8484
return ()
8585
try:
8686
encoded_uncles = self.db[uncles_hash]
87-
except KeyError:
87+
except KeyError as exc:
8888
raise HeaderNotFound(
8989
f"No uncles found for hash {uncles_hash!r}"
90-
)
90+
) from exc
9191
else:
9292
return tuple(rlp.decode(encoded_uncles, sedes=rlp.sedes.CountableList(BlockHeader)))
9393

eth/exceptions.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ class HeaderNotFound(PyEVMError):
3333
class BlockNotFound(PyEVMError):
3434
"""
3535
Raised when the block with the given number/hash does not exist.
36+
This will happen, for example, if the transactions or uncles are not
37+
saved in the database.
3638
"""
3739
pass
3840

eth/vm/forks/frontier/blocks.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
)
2020

2121
from eth_hash.auto import keccak
22+
from trie.exceptions import (
23+
MissingTrieNode,
24+
)
2225

2326
from eth.abc import (
2427
BlockHeaderAPI,
@@ -29,6 +32,10 @@
2932
from eth.constants import (
3033
EMPTY_UNCLE_HASH,
3134
)
35+
from eth.exceptions import (
36+
BlockNotFound,
37+
HeaderNotFound,
38+
)
3239
from eth.rlp.blocks import (
3340
BaseBlock,
3441
)
@@ -103,13 +110,21 @@ def get_receipts(self, chaindb: ChainDatabaseAPI) -> Tuple[ReceiptAPI, ...]:
103110
def from_header(cls, header: BlockHeaderAPI, chaindb: ChainDatabaseAPI) -> "FrontierBlock":
104111
"""
105112
Returns the block denoted by the given block header.
113+
114+
:raise eth.exceptions.BlockNotFound: if transactions or uncle headers are missing
106115
"""
107116
if header.uncles_hash == EMPTY_UNCLE_HASH:
108117
uncles: Tuple[BlockHeader, ...] = ()
109118
else:
110-
uncles = chaindb.get_block_uncles(header.uncles_hash)
111-
112-
transactions = chaindb.get_block_transactions(header, cls.get_transaction_class())
119+
try:
120+
uncles = chaindb.get_block_uncles(header.uncles_hash)
121+
except HeaderNotFound as exc:
122+
raise BlockNotFound(f"Uncles not found in database for {header}: {exc}") from exc
123+
124+
try:
125+
transactions = chaindb.get_block_transactions(header, cls.get_transaction_class())
126+
except MissingTrieNode as exc:
127+
raise BlockNotFound(f"Transactions not found in database for {header}: {exc}") from exc
113128

114129
return cls(
115130
header=header,

tests/database/test_eth1_chaindb.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
)
2222
from eth.db.schema import SchemaV1
2323
from eth.exceptions import (
24+
BlockNotFound,
2425
HeaderNotFound,
2526
ParentNotFound,
2627
ReceiptNotFound,
@@ -291,3 +292,19 @@ def test_chaindb_persist_unexecuted_block(chain,
291292
NUMBER_BLOCKS_IN_CHAIN,
292293
TRANSACTIONS_IN_BLOCK + 1,
293294
)
295+
296+
297+
def test_chaindb_raises_blocknotfound_on_missing_uncles(VM, chaindb, header):
298+
bad_header = header.copy(uncles_hash=b'unicorns' * 4)
299+
chaindb.persist_header(bad_header)
300+
301+
with pytest.raises(BlockNotFound):
302+
VM.get_block_class().from_header(bad_header, chaindb)
303+
304+
305+
def test_chaindb_raises_blocknotfound_on_missing_transactions(VM, chaindb, header):
306+
bad_header = header.copy(transaction_root=b'unicorns' * 4)
307+
chaindb.persist_header(bad_header)
308+
309+
with pytest.raises(BlockNotFound):
310+
VM.get_block_class().from_header(bad_header, chaindb)

0 commit comments

Comments
 (0)