|
1 |
| -import asyncio |
2 |
| -import logging |
3 |
| -from typing import ( |
4 |
| - Type, |
5 |
| - Union, |
6 |
| -) |
7 |
| - |
8 |
| -from eth.exceptions import HeaderNotFound |
9 |
| - |
10 |
| -from p2p.peer import PeerPool |
11 |
| - |
12 |
| -from .common.chain import BaseHeaderChainSyncer |
13 |
| -from .full.chain import FastChainSyncer, RegularChainSyncer |
14 |
| -from .light.chain import LightChainSyncer |
15 |
| - |
16 |
| - |
17 |
| -def _test() -> None: |
18 |
| - import argparse |
19 |
| - from pathlib import Path |
20 |
| - import signal |
21 |
| - from p2p import ecies |
22 |
| - from p2p.kademlia import Node |
23 |
| - from p2p.peer import DEFAULT_PREFERRED_NODES |
24 |
| - from eth.chains.ropsten import RopstenChain, ROPSTEN_GENESIS_HEADER, ROPSTEN_VM_CONFIGURATION |
25 |
| - from eth.chains.mainnet import MainnetChain, MAINNET_GENESIS_HEADER, MAINNET_VM_CONFIGURATION |
26 |
| - from eth.db.backends.level import LevelDB |
27 |
| - from tests.p2p.integration_test_helpers import ( |
28 |
| - FakeAsyncChainDB, FakeAsyncMainnetChain, FakeAsyncRopstenChain, FakeAsyncHeaderDB, |
29 |
| - connect_to_peers_loop) |
30 |
| - from trinity.protocol.eth.peer import ETHPeer # noqa: F811 |
31 |
| - from trinity.protocol.les.peer import LESPeer # noqa: F811 |
32 |
| - from trinity.utils.chains import load_nodekey |
33 |
| - |
34 |
| - parser = argparse.ArgumentParser() |
35 |
| - parser.add_argument('-db', type=str, required=True) |
36 |
| - parser.add_argument('-fast', action="store_true") |
37 |
| - parser.add_argument('-light', action="store_true") |
38 |
| - parser.add_argument('-nodekey', type=str) |
39 |
| - parser.add_argument('-enode', type=str, required=False, help="The enode we should connect to") |
40 |
| - parser.add_argument('-debug', action="store_true") |
41 |
| - args = parser.parse_args() |
42 |
| - |
43 |
| - logging.basicConfig( |
44 |
| - level=logging.INFO, format='%(asctime)s %(levelname)s: %(message)s', datefmt='%H:%M:%S') |
45 |
| - log_level = logging.INFO |
46 |
| - if args.debug: |
47 |
| - log_level = logging.DEBUG |
48 |
| - |
49 |
| - loop = asyncio.get_event_loop() |
50 |
| - |
51 |
| - base_db = LevelDB(args.db) |
52 |
| - headerdb = FakeAsyncHeaderDB(base_db) |
53 |
| - chaindb = FakeAsyncChainDB(base_db) |
54 |
| - try: |
55 |
| - genesis = chaindb.get_canonical_block_header_by_number(0) |
56 |
| - except HeaderNotFound: |
57 |
| - genesis = ROPSTEN_GENESIS_HEADER |
58 |
| - chaindb.persist_header(genesis) |
59 |
| - |
60 |
| - peer_class: Type[Union[ETHPeer, LESPeer]] = ETHPeer |
61 |
| - if args.light: |
62 |
| - peer_class = LESPeer |
63 |
| - |
64 |
| - if genesis.hash == ROPSTEN_GENESIS_HEADER.hash: |
65 |
| - network_id = RopstenChain.network_id |
66 |
| - vm_config = ROPSTEN_VM_CONFIGURATION # type: ignore |
67 |
| - chain_class = FakeAsyncRopstenChain |
68 |
| - elif genesis.hash == MAINNET_GENESIS_HEADER.hash: |
69 |
| - network_id = MainnetChain.network_id |
70 |
| - vm_config = MAINNET_VM_CONFIGURATION # type: ignore |
71 |
| - chain_class = FakeAsyncMainnetChain |
72 |
| - else: |
73 |
| - raise RuntimeError("Unknown genesis: %s", genesis) |
74 |
| - if args.nodekey: |
75 |
| - privkey = load_nodekey(Path(args.nodekey)) |
76 |
| - else: |
77 |
| - privkey = ecies.generate_privkey() |
78 |
| - peer_pool = PeerPool(peer_class, headerdb, network_id, privkey, vm_config) |
79 |
| - if args.enode: |
80 |
| - nodes = tuple([Node.from_uri(args.enode)]) |
81 |
| - else: |
82 |
| - nodes = DEFAULT_PREFERRED_NODES[network_id] |
83 |
| - |
84 |
| - asyncio.ensure_future(peer_pool.run()) |
85 |
| - asyncio.ensure_future(connect_to_peers_loop(peer_pool, nodes)) |
86 |
| - chain = chain_class(base_db) |
87 |
| - syncer: BaseHeaderChainSyncer = None |
88 |
| - if args.fast: |
89 |
| - syncer = FastChainSyncer(chain, chaindb, peer_pool) |
90 |
| - elif args.light: |
91 |
| - syncer = LightChainSyncer(chain, headerdb, peer_pool) |
92 |
| - else: |
93 |
| - syncer = RegularChainSyncer(chain, chaindb, peer_pool) |
94 |
| - syncer.logger.setLevel(log_level) |
95 |
| - syncer.min_peers_to_sync = 1 |
96 |
| - |
97 |
| - sigint_received = asyncio.Event() |
98 |
| - for sig in [signal.SIGINT, signal.SIGTERM]: |
99 |
| - loop.add_signal_handler(sig, sigint_received.set) |
100 |
| - |
101 |
| - async def exit_on_sigint() -> None: |
102 |
| - await sigint_received.wait() |
103 |
| - await peer_pool.cancel() |
104 |
| - await syncer.cancel() |
105 |
| - loop.stop() |
106 |
| - |
107 |
| - async def run() -> None: |
108 |
| - await syncer.run() |
109 |
| - syncer.logger.info("run() finished, exiting") |
110 |
| - sigint_received.set() |
111 |
| - |
112 |
| - # loop.set_debug(True) |
113 |
| - asyncio.ensure_future(exit_on_sigint()) |
114 |
| - asyncio.ensure_future(run()) |
115 |
| - loop.run_forever() |
116 |
| - loop.close() |
117 |
| - |
118 |
| - |
119 |
| -def _run_test(profile: bool) -> None: |
120 |
| - import cProfile, pstats # noqa |
121 |
| - |
122 |
| - async def mock_run_in_executor(self, callback, *args): # type: ignore |
123 |
| - return callback(*args) |
124 |
| - |
125 |
| - if profile: |
126 |
| - BaseHeaderChainSyncer._run_in_executor = mock_run_in_executor # type: ignore |
127 |
| - cProfile.run('_test()', 'stats') |
128 |
| - pstats.Stats('stats').strip_dirs().sort_stats('cumulative').print_stats(50) |
129 |
| - else: |
130 |
| - _test() |
131 |
| - |
132 |
| - |
133 |
| -if __name__ == "__main__": |
134 |
| - _run_test(profile=True) |
0 commit comments