Skip to content

Commit 5f140af

Browse files
authored
Merge pull request #995 from gsalgado/issue-529
Use persist_block() instead of persist_header() in FastChainSyncer
2 parents f90a868 + 8c2dd1b commit 5f140af

File tree

3 files changed

+23
-9
lines changed

3 files changed

+23
-9
lines changed

p2p/chain.py

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ async def _calculate_td(self, headers: Tuple[BlockHeader, ...]) -> int:
400400
async def _process_headers(
401401
self, peer: HeaderRequestingPeer, headers: Tuple[BlockHeader, ...]) -> int:
402402
target_td = await self._calculate_td(headers)
403-
await self._download_block_parts(
403+
bodies = await self._download_block_parts(
404404
target_td,
405405
[header for header in headers if not _is_body_empty(header)],
406406
self.request_bodies,
@@ -423,10 +423,18 @@ async def _process_headers(
423423
'receipt')
424424
self.logger.debug("Got block receipts for chain segment")
425425

426-
# FIXME: Get the bodies returned by self._download_block_parts above and use persit_block
427-
# here.
428426
for header in headers:
429-
await self.wait(self.db.coro_persist_header(header))
427+
if header.uncles_hash != EMPTY_UNCLE_HASH:
428+
body = cast(BlockBody, bodies[_body_key(header)])
429+
uncles = body.uncles
430+
else:
431+
uncles = tuple()
432+
vm_class = self.chain.get_vm_class_for_block_number(header.block_number)
433+
block_class = vm_class.get_block_class()
434+
# We don't need to use our block transactions here because persist_block() doesn't do
435+
# anything with them as it expects them to have been persisted already.
436+
block = block_class(header, uncles=uncles)
437+
await self.wait(self.db.coro_persist_block(block))
430438

431439
head = await self.wait(self.db.coro_get_canonical_head())
432440
return head.block_number
@@ -438,7 +446,8 @@ async def _download_block_parts(
438446
request_func: Callable[[int, List[BlockHeader]], int],
439447
download_queue: 'asyncio.Queue[Tuple[ETHPeer, List[DownloadedBlockPart]]]',
440448
key_func: Callable[[BlockHeader], Union[bytes, Tuple[bytes, bytes]]],
441-
part_name: str) -> 'List[DownloadedBlockPart]':
449+
part_name: str
450+
) -> 'Dict[Union[bytes, Tuple[bytes, bytes]], Union[BlockBody, List[Receipt]]]':
442451
"""Download block parts for the given headers, using the given request_func.
443452
444453
Retry timed out parts until we have the parts for all headers.
@@ -483,7 +492,7 @@ async def _download_block_parts(
483492
if key_func(header) not in received_keys
484493
]
485494

486-
return parts
495+
return dict((part.unique_key, part.part) for part in parts)
487496

488497
def _request_block_parts(
489498
self,
@@ -577,7 +586,7 @@ async def _handle_block_bodies(self,
577586

578587
# TODO: figure out why mypy is losing the type of the transactions_tries
579588
# so we can get rid of the ignore
580-
for (body, (tx_root, trie_dict_data)) in zip(bodies, transactions_tries): # type: ignore # noqa: E501
589+
for (body, (tx_root, trie_dict_data)) in zip(bodies, transactions_tries): # type: ignore
581590
await self.wait(self.db.coro_persist_trie_data_dict(trie_dict_data))
582591
uncles_hash = await self.wait(self.db.coro_persist_uncles(body.uncles))
583592
downloaded.append(DownloadedBlockPart(body, (tx_root, uncles_hash)))
@@ -686,7 +695,6 @@ async def _process_headers(
686695
'body')
687696
self.logger.info("Got block bodies for chain segment")
688697

689-
parts_by_key = dict((part.unique_key, part.part) for part in downloaded_parts)
690698
for header in headers:
691699
vm_class = self.chain.get_vm_class_for_block_number(header.block_number)
692700
block_class = vm_class.get_block_class()
@@ -695,7 +703,7 @@ async def _process_headers(
695703
transactions: List[BaseTransaction] = []
696704
uncles: List[BlockHeader] = []
697705
else:
698-
body = cast(eth.BlockBody, parts_by_key[_body_key(header)])
706+
body = cast(eth.BlockBody, downloaded_parts[_body_key(header)])
699707
tx_class = block_class.get_transaction_class()
700708
transactions = [tx_class.from_base_transaction(tx)
701709
for tx in body.transactions]

tests/p2p/integration_test_helpers.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class FakeAsyncHeaderDB(AsyncHeaderDB):
4242

4343

4444
class FakeAsyncChainDB(FakeAsyncHeaderDB, AsyncChainDB):
45+
coro_persist_block = async_passthrough('persist_block')
4546
coro_persist_uncles = async_passthrough('persist_uncles')
4647
coro_persist_trie_data_dict = async_passthrough('persist_trie_data_dict')
4748
coro_get = async_passthrough('get')

trinity/db/chain.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from eth_typing import Hash32
1515

1616
from evm.db.chain import ChainDB
17+
from evm.rlp.blocks import BaseBlock
1718
from evm.rlp.headers import BlockHeader
1819
from evm.rlp.receipts import Receipt
1920
from evm.rlp.transactions import BaseTransaction
@@ -29,6 +30,9 @@ class AsyncChainDB(ChainDB, AsyncHeaderDB):
2930
async def coro_get(self, key: bytes) -> bytes:
3031
raise NotImplementedError()
3132

33+
async def coro_persist_block(self, block: BaseBlock) -> None:
34+
raise NotImplementedError()
35+
3236
async def coro_persist_uncles(self, uncles: Tuple[BlockHeader]) -> Hash32:
3337
raise NotImplementedError()
3438

@@ -58,6 +62,7 @@ class ChainDBProxy(BaseProxy):
5862
coro_get_canonical_block_hash = async_method('get_canonical_block_hash')
5963
coro_get_canonical_block_header_by_number = async_method('get_canonical_block_header_by_number')
6064
coro_persist_header = async_method('persist_header')
65+
coro_persist_block = async_method('persist_block')
6166
coro_persist_uncles = async_method('persist_uncles')
6267
coro_persist_trie_data_dict = async_method('persist_trie_data_dict')
6368
coro_get_block_transactions = async_method('get_block_transactions')

0 commit comments

Comments
 (0)