def _test(): import argparse from evm.p2p import ecies from evm.chains.ropsten import RopstenChain, ROPSTEN_GENESIS_HEADER from evm.db.backends.level import LevelDB from evm.db.backends.memory import MemoryDB logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s') parser = argparse.ArgumentParser() parser.add_argument('-db', type=str, required=True) parser.add_argument('-root-hash', type=str, required=True, help='Hex encoded root hash') args = parser.parse_args() chaindb = ChainDB(MemoryDB()) chaindb.persist_header_to_db(ROPSTEN_GENESIS_HEADER) peer_pool = PeerPool(ETHPeer, chaindb, RopstenChain.network_id, ecies.generate_privkey()) asyncio.ensure_future(peer_pool.run()) state_db = LevelDB(args.db) root_hash = decode_hex(args.root_hash) downloader = StateDownloader(state_db, root_hash, peer_pool) loop = asyncio.get_event_loop() try: loop.run_until_complete(downloader.run()) except KeyboardInterrupt: pass loop.run_until_complete(downloader.stop()) loop.run_until_complete(peer_pool.stop()) loop.close()
def chaindb_mainnet_100(): """Return a chaindb with mainnet headers numbered from 0 to 100.""" here = os.path.dirname(__file__) headers_rlp = open(os.path.join(here, 'fixtures', 'sample_1000_headers_rlp'), 'r+b').read() headers = rlp.decode(headers_rlp, sedes=sedes.CountableList(BlockHeader)) chaindb = ChainDB(MemoryDB()) for i in range(0, 101): chaindb.persist_header_to_db(headers[i]) return chaindb
def _test(): import argparse import signal from evm.p2p import ecies from evm.chains.ropsten import RopstenChain, ROPSTEN_GENESIS_HEADER from evm.db.backends.level import LevelDB from evm.db.backends.memory import MemoryDB logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s') parser = argparse.ArgumentParser() parser.add_argument('-db', type=str, required=True) parser.add_argument('-root-hash', type=str, required=True, help='Hex encoded root hash') args = parser.parse_args() chaindb = ChainDB(MemoryDB()) chaindb.persist_header_to_db(ROPSTEN_GENESIS_HEADER) peer_pool = PeerPool(ETHPeer, chaindb, RopstenChain.network_id, ecies.generate_privkey()) asyncio.ensure_future(peer_pool.run()) state_db = LevelDB(args.db) root_hash = decode_hex(args.root_hash) downloader = StateDownloader(state_db, root_hash, peer_pool) loop = asyncio.get_event_loop() for sig in [signal.SIGINT, signal.SIGTERM]: loop.add_signal_handler(sig, downloader.cancel_token.trigger) async def run(): # downloader.run() will run in a loop until the SIGINT/SIGTERM handler triggers its cancel # token, at which point it returns and we stop the pool and downloader. await downloader.run() await peer_pool.stop() await downloader.stop() loop.run_until_complete(run()) loop.close()
def database_server_ipc_path(): core_db = MemoryDB() core_db[b'key-a'] = b'value-a' chaindb = ChainDB(core_db) # TODO: use a custom chain class only for testing. chaindb.persist_header_to_db(ROPSTEN_GENESIS_HEADER) with tempfile.TemporaryDirectory() as temp_dir: ipc_path = os.path.join(temp_dir, 'chaindb.ipc') chaindb_server_process = multiprocessing.Process( target=serve_chaindb, args=(core_db, ipc_path), ) chaindb_server_process.start() wait_for_ipc(ipc_path) try: yield ipc_path finally: kill_process_gracefully(chaindb_server_process)
def database_server_ipc_path(): core_db = MemoryDB() core_db[b'key-a'] = b'value-a' chaindb = ChainDB(core_db) # TODO: use a custom chain class only for testing. chaindb.persist_header_to_db(ROPSTEN_GENESIS_HEADER) with tempfile.TemporaryDirectory() as temp_dir: ipc_path = os.path.join(temp_dir, 'chaindb.ipc') chaindb_server_process = multiprocessing.Process( target=serve_chaindb, args=(core_db, ipc_path), ) chaindb_server_process.start() wait_for_ipc(ipc_path) try: yield ipc_path finally: kill_process_gracefully(chaindb_server_process)
def _test(): """ Create a Peer instance connected to a local geth instance and log messages exchanged with it. Use the following command line to run geth: ./build/bin/geth -vmodule p2p=4,p2p/discv5=0,eth/*=0 \ -nodekeyhex 45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8 \ -testnet -lightserv 90 """ import argparse import signal from evm.chains.ropsten import RopstenChain, ROPSTEN_GENESIS_HEADER from evm.db.backends.memory import MemoryDB logging.basicConfig(level=logging.DEBUG, format='%(levelname)s: %(message)s') # The default remoteid can be used if you pass nodekeyhex as above to geth. nodekey = keys.PrivateKey( decode_hex( "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8") ) remoteid = nodekey.public_key.to_hex() parser = argparse.ArgumentParser() parser.add_argument('-remoteid', type=str, default=remoteid) parser.add_argument('-light', action='store_true', help="Connect as a light node") args = parser.parse_args() peer_class = ETHPeer # type: ignore if args.light: peer_class = LESPeer # type: ignore remote = Node(keys.PublicKey(decode_hex(args.remoteid)), Address('127.0.0.1', 30303, 30303)) chaindb = ChainDB(MemoryDB()) chaindb.persist_header_to_db(ROPSTEN_GENESIS_HEADER) network_id = RopstenChain.network_id loop = asyncio.get_event_loop() peer = loop.run_until_complete( asyncio.wait_for( handshake(remote, ecies.generate_privkey(), peer_class, chaindb, network_id), HANDSHAKE_TIMEOUT)) async def request_stuff(): # Request some stuff from ropsten's block 2440319 # (https://ropsten.etherscan.io/block/2440319), just as a basic test. nonlocal peer block_hash = decode_hex( '0x59af08ab31822c992bb3dad92ddb68d820aa4c69e9560f07081fa53f1009b152' ) if peer_class == ETHPeer: peer = cast(ETHPeer, peer) peer.sub_proto.send_get_block_headers(block_hash, 1) peer.sub_proto.send_get_block_bodies([block_hash]) peer.sub_proto.send_get_receipts([block_hash]) else: peer = cast(LESPeer, peer) request_id = 1 peer.sub_proto.send_get_block_headers(block_hash, 1, request_id) peer.sub_proto.send_get_block_bodies([block_hash], request_id + 1) peer.sub_proto.send_get_receipts(block_hash, request_id + 2) for sig in [signal.SIGINT, signal.SIGTERM]: loop.add_signal_handler(sig, peer.cancel_token.trigger) asyncio.ensure_future(request_stuff()) loop.run_until_complete(peer.run()) loop.close()
async def test_lightchain_integration(request, event_loop): """Test LightChain against a local geth instance. This test assumes a geth/ropsten instance is listening on 127.0.0.1:30303 and serving light clients. In order to achieve that, simply run it with the following command line: $ geth -nodekeyhex 45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8 \ -testnet -lightserv 90 """ # TODO: Implement a pytest fixture that runs geth as above, so that we don't need to run it # manually. if not pytest.config.getoption("--integration"): pytest.skip("Not asked to run integration tests") chaindb = ChainDB(MemoryDB()) chaindb.persist_header_to_db(ROPSTEN_GENESIS_HEADER) peer_pool = LocalGethPeerPool(LESPeer, chaindb, ROPSTEN_NETWORK_ID, ecies.generate_privkey()) chain = IntegrationTestLightChain(chaindb, peer_pool) asyncio.ensure_future(peer_pool.run()) asyncio.ensure_future(chain.run()) await asyncio.sleep( 0) # Yield control to give the LightChain a chance to start def finalizer(): event_loop.run_until_complete(peer_pool.stop()) event_loop.run_until_complete(chain.stop()) request.addfinalizer(finalizer) n = 11 # Wait for the chain to sync a few headers. async def wait_for_header_sync(block_number): while chaindb.get_canonical_head().block_number < block_number: await asyncio.sleep(0.1) await asyncio.wait_for(wait_for_header_sync(n), 2) # https://ropsten.etherscan.io/block/11 b = await chain.get_canonical_block_by_number(n) assert isinstance(b, FrontierBlock) assert b.number == 11 assert encode_hex(b.hash) == ( '0xda882aeff30f59eda9da2b3ace3023366ab9d4219b5a83cdd589347baae8678e') assert len(b.transactions) == 15 assert isinstance(b.transactions[0], b.transaction_class) receipts = await chain.get_receipts(b.hash) assert len(receipts) == 15 assert encode_hex(keccak(rlp.encode(receipts[0]))) == ( '0xf709ed2c57efc18a1675e8c740f3294c9e2cb36ba7bb3b89d3ab4c8fef9d8860') assert len(chain.peer_pool.peers) == 1 head_info = chain.peer_pool.peers[0].head_info head = await chain.get_block_by_hash(head_info.block_hash) assert head.number == head_info.block_number # In order to answer queries for contract code, geth needs the state trie entry for the block # we specify in the query, but because of fast sync we can only assume it has that for recent # blocks, so we use the current head to lookup the code for the contract below. # https://ropsten.etherscan.io/address/0x95a48dca999c89e4e284930d9b9af973a7481287 contract_addr = decode_hex('95a48dca999c89e4e284930d9b9af973a7481287') contract_code = await chain.get_contract_code(head.hash, keccak(contract_addr)) assert encode_hex(keccak(contract_code)) == ( '0x1e0b2ad970b365a217c40bcf3582cbb4fcc1642d7a5dd7a82ae1e278e010123e') account = await chain.get_account(head.hash, contract_addr) assert account.code_hash == keccak(contract_code) assert account.balance == 0
def get_fresh_mainnet_chaindb(): chaindb = ChainDB(MemoryDB()) chaindb.persist_header_to_db(MAINNET_GENESIS_HEADER) return chaindb