async def test_incremental_header_sync(request, event_loop, chaindb_mainnet_100): # Here, server will be a peer with a pre-populated chaindb, and we'll use it to send Announce # msgs to the client, which will then ask the server for any headers it's missing until their # chaindbs are in sync. light_chain, client, server = await get_lightchain_with_peers( request, event_loop, get_fresh_mainnet_chaindb()) # We start the client/server with fresh chaindbs above because we don't want them to start # syncing straight away -- instead we want to manually trigger incremental syncs by having the # server send Announce messages. We're now ready to give our server a populated chaindb. server.chaindb = chaindb_mainnet_100 # The server now announces block #10 as the new head... server.send_announce(head_number=10) # ... and we wait for the client to process that and request all headers it's missing up to # block #10. header_10 = server.chaindb.get_canonical_block_header_by_number(10) await wait_for_head(light_chain.chaindb, header_10) assert_canonical_chains_are_equal(light_chain.chaindb, server.chaindb, 10) # Now the server announces block 100 as its current head... server.send_announce(head_number=100) # ... and the client should then fetch headers from 10-100. header_100 = server.chaindb.get_canonical_block_header_by_number(100) await wait_for_head(light_chain.chaindb, header_100) assert_canonical_chains_are_equal(light_chain.chaindb, server.chaindb, 100)
async def get_lightchain_with_peers(request, event_loop, server_peer_chaindb): """Return a LightChainForTests instance with a client/server peer pair. The server is a LESPeerServer instance that can be used to send Announce and BlockHeaders messages, and the client will be configured with the LightChain's msg_handler so that a sync request is added to the LightChain's queue every time a new Announce message is received. """ chaindb = get_fresh_mainnet_chaindb() light_chain = LightChainForTests(chaindb) asyncio.ensure_future(light_chain.run()) await asyncio.sleep( 0) # Yield control to give the LightChain a chance to start def finalizer(): event_loop.run_until_complete(light_chain.stop()) request.addfinalizer(finalizer) client, server = await get_client_and_server_peer_pair( request, event_loop, client_chaindb=chaindb, client_received_msg_callback=light_chain.msg_handler, server_chaindb=server_peer_chaindb, ) return light_chain, client, server