From c122e8eee8ea10777a2f493a94e79c3233417526 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= <mich@elmueller.net> Date: Fri, 15 Feb 2019 15:59:53 +0100 Subject: [PATCH] Fix --import-blocks (#1807) * Encode count of exported blocks correctly There was a type mismatch: import used u32, export used Number. * Wait for import to finish The issue was that even though the import thread was still running, the main thread exited. * Remove superfluous parentheses * Improve structure, add proofs for expects * Unify types for export/import length --- substrate/core/service/src/chain_ops.rs | 44 +++++++++++++++++++++---- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/substrate/core/service/src/chain_ops.rs b/substrate/core/service/src/chain_ops.rs index ea0311f3b56..953bb8c3751 100644 --- a/substrate/core/service/src/chain_ops.rs +++ b/substrate/core/service/src/chain_ops.rs @@ -21,7 +21,7 @@ use futures::Future; use log::{info, warn}; use runtime_primitives::generic::{SignedBlock, BlockId}; -use runtime_primitives::traits::{As, Block, Header}; +use runtime_primitives::traits::{As, Block, Header, NumberFor}; use consensus_common::import_queue::{ImportQueue, IncomingBlock, Link}; use network::message; @@ -66,7 +66,10 @@ pub fn export_blocks<F, E, W>( }); info!("Exporting blocks from #{} to #{}", block, last); if !json { - output.write(&(last - block + As::sa(1)).encode())?; + let last_: u64 = last.as_(); + let block_: u64 = block.as_(); + let len: u64 = last_ - block_ + 1; + output.write(&len.encode())?; } loop { @@ -95,6 +98,25 @@ pub fn export_blocks<F, E, W>( Ok(()) } +struct WaitLink { + wait_send: std::sync::mpsc::Sender<()>, +} + +impl WaitLink { + fn new(wait_send: std::sync::mpsc::Sender<()>) -> WaitLink { + WaitLink { + wait_send, + } + } +} + +impl<B: Block> Link<B> for WaitLink { + fn block_imported(&self, _hash: &B::Hash, _number: NumberFor<B>) { + self.wait_send.send(()) + .expect("Unable to notify main process; if the main process panicked then this thread would already be dead as well. qed."); + } +} + /// Import blocks from a binary stream. pub fn import_blocks<F, E, R>( mut config: FactoryFullConfiguration<F>, @@ -103,13 +125,13 @@ pub fn import_blocks<F, E, R>( ) -> error::Result<()> where F: ServiceFactory, E: Future<Item=(),Error=()> + Send + 'static, R: Read, { - struct DummyLink; - impl<B: Block> Link<B> for DummyLink { } - let client = new_client::<F>(&config)?; // FIXME #1134 this shouldn't need a mutable config. let queue = components::FullComponents::<F>::build_import_queue(&mut config, client.clone())?; - queue.start(DummyLink)?; + + let (wait_send, wait_recv) = std::sync::mpsc::channel(); + let wait_link = WaitLink::new(wait_send); + queue.start(wait_link)?; let (exit_send, exit_recv) = std::sync::mpsc::channel(); ::std::thread::spawn(move || { @@ -117,7 +139,7 @@ pub fn import_blocks<F, E, R>( let _ = exit_send.send(()); }); - let count: u32 = Decode::decode(&mut input).ok_or("Error reading file")?; + let count: u64 = Decode::decode(&mut input).ok_or("Error reading file")?; info!("Importing {} blocks", count); let mut block_count = 0; for b in 0 .. count { @@ -155,6 +177,14 @@ pub fn import_blocks<F, E, R>( info!("#{}", b); } } + + let mut blocks_imported = 0; + while blocks_imported < count { + wait_recv.recv() + .expect("Importing thread has panicked. Then the main process will die before this can be reached. qed."); + blocks_imported += 1; + } + info!("Imported {} blocks. Best: #{}", block_count, client.info()?.chain.best_number); Ok(()) -- GitLab