|
4 | 4 | Callable,
|
5 | 5 | Dict,
|
6 | 6 | List,
|
7 |
| - Set, |
8 | 7 | Tuple,
|
9 | 8 | )
|
10 | 9 |
|
11 | 10 | from eth_utils import (
|
12 | 11 | encode_hex,
|
13 | 12 | )
|
14 |
| -from eth.utils.logging import TraceLogger |
15 | 13 |
|
16 | 14 | from eth_typing import (
|
17 | 15 | Hash32
|
18 | 16 | )
|
19 | 17 |
|
| 18 | +from eth.db.backends.base import BaseDB |
| 19 | +from eth.utils.logging import TraceLogger |
| 20 | + |
20 | 21 | from trie.constants import (
|
21 | 22 | NODE_TYPE_BLANK,
|
22 | 23 | NODE_TYPE_BRANCH,
|
@@ -111,16 +112,24 @@ def _get_children(node: Hash32, depth: int
|
111 | 112 |
|
112 | 113 | class HexaryTrieSync:
|
113 | 114 |
|
114 |
| - def __init__(self, root_hash: Hash32, db: AsyncBaseDB, logger: TraceLogger) -> None: |
| 115 | + def __init__(self, |
| 116 | + root_hash: Hash32, |
| 117 | + db: AsyncBaseDB, |
| 118 | + nodes_cache: BaseDB, |
| 119 | + logger: TraceLogger) -> None: |
| 120 | + # Nodes that haven't been requested yet. |
115 | 121 | self.queue: List[SyncRequest] = []
|
| 122 | + # Nodes that have been requested to a peer, but not yet committed to the DB, either |
| 123 | + # because we haven't processed a reply containing them or because some of their children |
| 124 | + # haven't been retrieved/committed yet. |
116 | 125 | self.requests: Dict[Hash32, SyncRequest] = {}
|
117 | 126 | self.db = db
|
118 | 127 | self.root_hash = root_hash
|
119 | 128 | self.logger = logger
|
120 | 129 | # A cache of node hashes we know to exist in our DB, used to avoid querying the DB
|
121 | 130 | # unnecessarily as that's the main bottleneck when dealing with a large DB like for
|
122 | 131 | # ethereum's mainnet/ropsten.
|
123 |
| - self._existing_nodes: Set[Hash32] = set() |
| 132 | + self.nodes_cache = nodes_cache |
124 | 133 | self.committed_nodes = 0
|
125 | 134 | if root_hash in self.db:
|
126 | 135 | self.logger.info("Root node (%s) already exists in DB, nothing to do", root_hash)
|
@@ -150,11 +159,11 @@ async def schedule(self, node_key: Hash32, parent: SyncRequest, depth: int,
|
150 | 159 | leaf_callback: Callable[[bytes, 'SyncRequest'], Awaitable[None]],
|
151 | 160 | is_raw: bool = False) -> None:
|
152 | 161 | """Schedule a request for the node with the given key."""
|
153 |
| - if node_key in self._existing_nodes: |
| 162 | + if node_key in self.nodes_cache: |
154 | 163 | self.logger.trace("Node %s already exists in db", encode_hex(node_key))
|
155 | 164 | return
|
156 | 165 | if await self.db.coro_exists(node_key):
|
157 |
| - self._existing_nodes.add(node_key) |
| 166 | + self.nodes_cache[node_key] = b'' |
158 | 167 | self.logger.trace("Node %s already exists in db", encode_hex(node_key))
|
159 | 168 | return
|
160 | 169 | self._schedule(node_key, parent, depth, leaf_callback, is_raw)
|
@@ -224,7 +233,7 @@ async def commit(self, request: SyncRequest) -> None:
|
224 | 233 | """
|
225 | 234 | self.committed_nodes += 1
|
226 | 235 | await self.db.coro_set(request.node_key, request.data)
|
227 |
| - self._existing_nodes.add(request.node_key) |
| 236 | + self.nodes_cache[request.node_key] = b'' |
228 | 237 | self.requests.pop(request.node_key)
|
229 | 238 | for ancestor in request.parents:
|
230 | 239 | ancestor.dependencies -= 1
|
|
0 commit comments