Skip to content

Commit 74c48d1

Browse files
committed
chain.validate_chain refactor & semantic cleanup
1 parent 680b5e5 commit 74c48d1

File tree

1 file changed

+24
-14
lines changed

1 file changed

+24
-14
lines changed

eth/chains/base.py

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@
3434
from eth_utils import (
3535
encode_hex,
3636
)
37+
from eth_utils.toolz import (
38+
concatv,
39+
sliding_window,
40+
)
3741

3842
from eth.constants import (
3943
BLANK_ROOT_HASH,
@@ -318,28 +322,34 @@ def validate_uncles(self, block: BaseBlock) -> None:
318322
@classmethod
319323
def validate_chain(
320324
cls,
321-
parent: BlockHeader,
322-
chain: Tuple[BlockHeader, ...],
325+
root: BlockHeader,
326+
descendants: Tuple[BlockHeader, ...],
323327
seal_check_random_sample_rate: int = 1) -> None:
328+
"""
329+
Validate that all of the descendents are valid, given that the root header is valid.
324330
325-
all_indices = list(range(len(chain)))
331+
By default, check the seal validity (Proof-of-Work on Ethereum 1.x mainnet) of all headers.
332+
This can be expensive. Instead, check a random sample of seals using
333+
seal_check_random_sample_rate.
334+
"""
335+
336+
all_indices = range(len(descendants))
326337
if seal_check_random_sample_rate == 1:
327-
headers_to_check_seal = set(all_indices)
338+
indices_to_check_seal = set(all_indices)
328339
else:
329340
sample_size = len(all_indices) // seal_check_random_sample_rate
330-
headers_to_check_seal = set(random.sample(all_indices, sample_size))
341+
indices_to_check_seal = set(random.sample(all_indices, sample_size))
342+
343+
header_pairs = sliding_window(2, concatv([root], descendants))
331344

332-
for i, header in enumerate(chain):
333-
if header.parent_hash != parent.hash:
345+
for index, (parent, child) in enumerate(header_pairs):
346+
if child.parent_hash != parent.hash:
334347
raise ValidationError(
335348
"Invalid header chain; {} has parent {}, but expected {}".format(
336-
header, header.parent_hash, parent.hash))
337-
vm_class = cls.get_vm_class_for_block_number(header.block_number)
338-
if i in headers_to_check_seal:
339-
vm_class.validate_header(header, parent, check_seal=True)
340-
else:
341-
vm_class.validate_header(header, parent, check_seal=False)
342-
parent = header
349+
child, child.parent_hash, parent.hash))
350+
should_check_seal = index in indices_to_check_seal
351+
vm_class = cls.get_vm_class_for_block_number(child.block_number)
352+
vm_class.validate_header(child, parent, check_seal=should_check_seal)
343353

344354

345355
class Chain(BaseChain):

0 commit comments

Comments
 (0)