|
34 | 34 | from eth_utils import (
|
35 | 35 | encode_hex,
|
36 | 36 | )
|
| 37 | +from eth_utils.toolz import ( |
| 38 | + concatv, |
| 39 | + sliding_window, |
| 40 | +) |
37 | 41 |
|
38 | 42 | from eth.constants import (
|
39 | 43 | BLANK_ROOT_HASH,
|
@@ -318,28 +322,34 @@ def validate_uncles(self, block: BaseBlock) -> None:
|
318 | 322 | @classmethod
|
319 | 323 | def validate_chain(
|
320 | 324 | cls,
|
321 |
| - parent: BlockHeader, |
322 |
| - chain: Tuple[BlockHeader, ...], |
| 325 | + root: BlockHeader, |
| 326 | + descendants: Tuple[BlockHeader, ...], |
323 | 327 | 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. |
324 | 330 |
|
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)) |
326 | 337 | if seal_check_random_sample_rate == 1:
|
327 |
| - headers_to_check_seal = set(all_indices) |
| 338 | + indices_to_check_seal = set(all_indices) |
328 | 339 | else:
|
329 | 340 | 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)) |
331 | 344 |
|
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: |
334 | 347 | raise ValidationError(
|
335 | 348 | "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) |
343 | 353 |
|
344 | 354 |
|
345 | 355 | class Chain(BaseChain):
|
|
0 commit comments